Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.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++_C_Alignment_Clang_Llvm - Fatal编程技术网

C++ 为什么铿锵输出对齐是特定的

C++ 为什么铿锵输出对齐是特定的,c++,c,alignment,clang,llvm,C++,C,Alignment,Clang,Llvm,假设我有一个c语言的basic程序,我用叮当声编译它,如下所示: #include "stdio.h" int x = 0x7FFFFFFF; int main(void) { printf("%d\n",x); } 使用clang-emit llvm temp.c-fno rtti-O3-S编译此文件将生成以下位代码: ; ModuleID = 'temp.c' target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32

假设我有一个c语言的basic程序,我用叮当声编译它,如下所示:

#include "stdio.h"
int x = 0x7FFFFFFF;
int main(void)
{

    printf("%d\n",x);
}
使用
clang-emit llvm temp.c-fno rtti-O3-S
编译此文件将生成以下位代码:

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

@x = global i32 2147483647, align 4
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1

; Function Attrs: nounwind
define i32 @main() #0 {
entry:
  %0 = load i32, i32* @x, align 4, !tbaa !1
  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0) #1
  ret i32 0
}

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

attributes #0 = { 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" }
attributes #1 = { nounwind }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.7.1 "}
!1 = !{!2, !2, i64 0}
!2 = !{!"int", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
现在我真正的问题是关于引用变量
x
的行。如果您注意到,
x
似乎被声明为一个对齐的变量(它与4对齐)

clang如何知道
int
s应该对齐?我的主张是,clang没有任何关于变量对齐的线索,因为这取决于您使用的后端。例如,我可以使用一个8位机器的后端,那么它就根本不需要对齐

所以我的问题是:既然这真的是不可能的,为什么clang会猜测对齐呢

模块可以指定特定于目标的数据布局字符串,该字符串指定如何在内存中布局数据。数据布局的语法很简单:

target datalayout = "layout specification"
布局规范由一系列规范组成,规范之间用减号('-')分隔。每个规范都以一个字母开头,字母后可能包含其他信息,以定义数据布局的某些方面。接受的规格如下:

[……]

n

这为目标CPU指定一组本机整数宽度(以位为单位)。例如,对于32位PowerPC,它可能包含n32;对于PowerPC 64,它可能包含n32:64;对于X86-64,它可能包含n8:16:32:64。该集合的元素被认为可以有效地支持大多数通用算术运算

重点矿山

当LLVM确定给定类型的对齐方式时,它使用以下规则:

如果所寻求的类型与其中一种规格完全匹配,则使用该规格

  • 如果找不到匹配项,并且查找的类型是整数类型,则 大于数据位宽度的最小整数类型 使用搜索类型
  • 如果没有任何规格大于位宽度,则 使用最大整数类型。例如,给定默认值 在上述规格中,i7类型将使用i8的对齐方式(下一步) 最大),而i65和i256都将使用i64的对齐方式 (指定最大值)
  • 如果未找到匹配项,并且所查找的类型是向量类型,则 小于搜索向量类型的最大向量类型将 被用作退路。发生这种情况是因为可以 例如,以64为单位实现
  • ++全局变量**

    [……]

    可以为全局值指定显式对齐,该值必须是2的幂如果不存在,或者如果对齐设置为零,则目标会将全局对齐设置为其认为方便的任何位置。如果指定了显式对齐,则强制全局对齐


    emphasis mine因
    target triple=“i686 pc linux gnu”而不知道吗
    ?您下载了一个特定拱门的铿锵版本…@NathanOliver这是可能的…。我甚至没有看到……编译器将为它所在的平台编译它,除非您指定不同的AFAIK。@DarthRubik它可能是。好的,那么问题是:如果编译器已经知道an
    int
    是(从您刚才描述的目标datalayout中)那么为什么它以后会指定对齐方式?(它不需要这样做,因为它已经知道int与4对齐)I已更新。每次遇到基于布局和规范的变量时,都会对对齐进行评估。