C++ 带有-fno内置项的GCC似乎不起作用
我想将GCC内置函数C++ 带有-fno内置项的GCC似乎不起作用,c++,gcc,memcpy,C++,Gcc,Memcpy,我想将GCC内置函数memcpy与libc中的函数进行比较。但是,似乎忽略了-fno-builtin或-fno-builtin memcpy的所有迭代 //g++ -O3 foo.cpp -S or //g++ -O3 -fno-builtin foo.cpp -S #include <string.h> int main() { volatile int n = 1000; //int n = 1000; float *x = new float[1000]
memcpy
与libc中的函数进行比较。但是,似乎忽略了-fno-builtin
或-fno-builtin memcpy
的所有迭代
//g++ -O3 foo.cpp -S or
//g++ -O3 -fno-builtin foo.cpp -S
#include <string.h>
int main() {
volatile int n = 1000;
//int n = 1000;
float *x = new float[1000];
float *y = new float[1000];
memcpy(y,x,sizeof(float)*n);
//__builtin_memcpy(y,x,sizeof(float)*n);
}
//g++-O3 foo.cpp-S或
//g++-O3-fno内置foo.cpp-S
#包括
int main(){
挥发性int n=1000;
//int n=1000;
浮动*x=新浮动[1000];
浮动*y=新浮动[1000];
memcpy(y,x,sizeof(float)*n);
//__内置内存(y、x、尺寸(浮动)*n);
}
我发现,如果上述源代码中的n
不是易失性的,那么它会内联内置代码。但是,当n
变为易失性时,它将调用函数\uuu memcpy\u chk
,该函数是的一个版本。如果n
是易失性的,而我调用\uu builtin\u memcpy
,那么它调用memcpy
因此,到目前为止,我的结论是,只有在编译时已知n
时才会生成内置代码,-fno-builtin
是无用的。我使用的是GCC4.8.2
-fno内置是否过时?是否有一种方法可以从C库中调用GCC调用<代码> MycPy < /> >,即使在编译时知道代码> N>代码>?< P> > P>注释:因为您正在编译C++代码,如果应用了,我不确定100%。
C标准要求所有库函数(除非另有明确指示)都有一个地址,并且可以是&
地址运算符的操作数。这是因为它允许某些/大多数函数作为函数宏实现,但在某些情况下仍应表现为实际变量/函数。为了避免使用它的宏版本,您只需要在memcpy
标记和(
标记(正如@Zach指出的,空格不够)之间添加一些内容:
这将强制使用实际函数,这将避免任何类型的内置宏定义
-O3
优化也可能扫描某些函数调用(例如memcpy
)并用内置调用替换它们,而不考虑-fno-builtin
-fno-builtin
和-fno-builtin memcpy
这两个选项都具有gcc 4.9.1所期望的效果。这可能只是gcc 4.8.2中的一个错误;这种特定的选项组合没有被广泛使用。-ffreserving
是一个相关的开关这可能会对4.8.2产生您想要的效果
请注意,编译器有权将您的程序优化到
int main() { return 0; }
当调用时没有-fno内置(-memcpy)
或-f重新理解
,即使n
是易变的
,因为它可以(原则上)证明程序作为一个整体没有可观察到的副作用,或者其行为是未定义的。(当n
不是volatile
时,就不会有UB;如果读取时n
在[0,1000]
范围之外,并且volatile
告诉编译器它不能假定n
有程序写入的值,就会发生UB。)您的问题很可能是glibc,而不是gcc。您没有指定,但您可能正在使用Ubuntu,默认情况下它定义了-D\u FORTIFY\u SOURCE=2
。这会提示glibc头提供memcpy
的内联定义,并转发到\u memcpy\u chk
一个memcpy
的宏版本仍将在memcpy
和(
。但是,在标记memcpy
周围加上括号确实符合您的描述。此外,我可以权威地说,-fno-builtin
在所有优化级别上都应该满足OP的期望。我用GCC和g+尝试了您的建议(这个代码在C中编译得很好,所以我不确定C++标签是否更好),它们没有区别。就像“代码> -O3
(
作为下一个预处理标记)”开头的句子(我的重点是:空格不是预处理标记))显然(如果您习惯了standardese,那么)表示函数宏是扩展的,即使宏名称和(
(2/2)之间存在任何数量的空格我尝试了-ff重新理解
。这没有什么区别。我必须安装gcc 4.9.1来验证您的答案。我查看了http://gcc.godbolt.org/
,我可以确认-fno-builtin
按照GCC 4.9中的预期工作,而不是GCC 4.8.1中的预期工作。我检查了GCC 4.4至4.9,并且4.9是唯一得到它的rect.ICC也是正确的。当我传递-fno-builtin
时,它使用memcpy
,没有它,它使用\u intel\u fast\u memcpy
。很明显,编译器没有优化代码。从汇编程序代码中可以看出这一点。我刚刚注意到,在这个问题和您的评论中,您拼写错误-fno-builtin
几种不同的方法。检查以确保不会影响结果。正确的拼写是“bu i l t i n”。@Zack,谢谢你找到拼写错误。我希望我都解决了。我确实有点太马虎了(当我在测试示例中应该使用malloc时,我也使用了new
——在我自己的代码中,我使用了\u mm\u malloc
)。但是GCC会抱怨我是否使用了任何拼写错误。但是如果你想自己检查,请将代码放在int上面(删除volatile)
int main() { return 0; }