Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是叮当声';它坏了吗?_C++_Optimization_Clang_Llvm - Fatal编程技术网

C++ 是叮当声';它坏了吗?

C++ 是叮当声';它坏了吗?,c++,optimization,clang,llvm,C++,Optimization,Clang,Llvm,如果将C++程序插入到 CLAN(版本3.7) 并使用clang-emit llvm main.cpp-fno rtti-O3-S进行编译,然后得到以下字节码: ; ModuleID = 'main.cpp' target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" target triple = "i686-pc-linux-gnu" %struct.B = type { %struct.A, i32 } %stru

如果将C++程序插入到<代码> CLAN<代码>(版本3.7)

并使用
clang-emit llvm main.cpp-fno rtti-O3-S
进行编译,然后得到以下字节码:

; ModuleID = 'main.cpp'
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-pc-linux-gnu"

%struct.B = type { %struct.A, i32 }
%struct.A = type { i32 (...)** }

$_ZN1B3fooEv = comdat any

$_ZTV1B = comdat any

@thing = global i64 0, align 8
@other = global float 1.000000e+01, align 4
@b = global %struct.B { %struct.A { i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**) }, i32 12345 }, align 4
@_ZTV1B = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.B*)* @_ZN1B3fooEv to i8*)], comdat, align 4
@.str = private unnamed_addr constant [19 x i8] c"This is a test %d\0A\00", align 1
@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer

; Function Attrs: nounwind readnone
define void @__cxa_pure_virtual() #0 {
entry:
  ret void
}

define i32 @main() #1 {
entry:
  %0 = load i64, i64* @thing, align 8, !tbaa !1
  %inc = add i64 %0, 1
  store i64 %inc, i64* @thing, align 8, !tbaa !1
  %1 = load float, float* @other, align 4, !tbaa !5
  %mul = fmul float %1, 0x400921FA00000000
  store float %mul, float* @other, align 4, !tbaa !5
  %vtable = load void (%struct.A*)**, void (%struct.A*)*** bitcast (%struct.B* @b to void (%struct.A*)***), align 4, !tbaa !7
  %2 = load void (%struct.A*)*, void (%struct.A*)** %vtable, align 4
  tail call void %2(%struct.A* getelementptr inbounds (%struct.B, %struct.B* @b, i32 0, i32 0))
  ret i32 0
}

; Function Attrs: nounwind
define linkonce_odr void @_ZN1B3fooEv(%struct.B* nocapture readonly %this) unnamed_addr #2 comdat align 2 {
entry:
  %x = getelementptr inbounds %struct.B, %struct.B* %this, i32 0, i32 1
  %0 = load i32, i32* %x, align 4, !tbaa !9
  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), i32 %0)
  ret void
}

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #2

attributes #0 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.7.1 "}
!1 = !{!2, !2, i64 0}
!2 = !{!"long long", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !6, i64 0}
!6 = !{!"float", !3, i64 0}
!7 = !{!8, !8, i64 0}
!8 = !{!"vtable pointer", !4, i64 0}
!9 = !{!10, !11, i64 4}
!10 = !{!"_ZTS1B", !11, i64 4}
!11 = !{!"int", !3, i64 0}
如果你看一下主函数,我有两个变量是无用的。当然,我增加了一个,对另一个做了一些乘法,但我从来没有使用过其中的值

但是如果你看字节码的输出,它看起来仍然在做无用的数学运算


这只是我还是一个bug?

这些变量是全局范围内的变量。编译器根本无法确定这些变量是否可以在其他翻译单元中声明和引用


如果任何一个现代C++编译器都足够复杂,可以确定执行流不能以定义的方式逃离这个翻译单元,那么在这个翻译单元中优化掉未使用的全局变量是安全的。

< P>不,我不认为这是一个bug,因为你的变量是全局变量。 Clang无法删除此数学,因为它不知道任何外部调用的函数(如printf函数,在不同的转换单元中)不声明
extern float other并以某种方式使用它

试着写:

int main()
{
    uint64_t thing = 0;
    float other = 10.0f;
    B b(12345);

    thing++;
    A* a = &b;
    other *= 3.14159f;
    a->foo();
}

我怀疑这是编译器的错误,更可能的是你做错了什么。“执行流无法逃离这个翻译单元”-其他TUs中的其他静态初始化呢?用于初始化其他TU中全局和静态变量的构造函数和函数可以在
main()
启动之前运行更多代码。因此,变量必须保持不变(除非链接时间优化证明它们没有在任何地方使用),但是
main()
中的写操作似乎很适合删除,因为即使其他TU中的任何c-tor启动了线程,这里的访问也不是原子的,因此是UB。很有意思。LTO可以抓住这个。
int main()
{
    uint64_t thing = 0;
    float other = 10.0f;
    B b(12345);

    thing++;
    A* a = &b;
    other *= 3.14159f;
    a->foo();
}