【发布时间】:2013-05-10 21:56:47
【问题描述】:
获取此示例代码:
#include <string.h>
#define STRcommaLEN(str) (str), (sizeof(str)-1)
int main() {
const char * b = "string2";
const char * c = "string3";
strncmp(b, STRcommaLEN(c));
}
如果你不在 GCC 中使用优化,一切都很好,但如果你添加 -O1 及以上,如gcc -E -std=gnu99 -Wall -Wextra -c -I/usr/local/include -O1 sample.c,strncmp 成为一个宏,并且在预处理阶段 STRcommaLen 没有展开。事实上,结果“代码”strncmp 的参数被完全剥离。
我知道如果我添加 #define NEWstrncmp(a, b) strncmp (a, b) 并改用它,问题就会消失。但是,将您自己的函数映射到每个可能成为宏的标准函数似乎并不是一个很好的解决方案。
我尝试找到负责它的特定优化但失败了。事实上,如果我将 -O1 替换为根据man gcc 启用的所有标志,问题就会消失。我的结论是 -O1 添加了一些不受标志控制的优化,这就是其中之一。
您将如何以通用方式处理此问题?可能有一些我不熟悉的宏魔法或我没有看过的编译器标志?我们有许多宏和大量代码库 - 编写此代码只是为了演示一个示例。
顺便说一句,GCC 版本/平台是gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)。
谢谢, 阿伦
【问题讨论】:
-
如果优化破坏了一个有效的程序,那就是应该报告的编译器错误。
-
与gcc无关,是glibc选择将strncmp做成宏。
-
glibc 这样做是完全合法的,参见 C99 7.1.4,第一段。 “在头文件中声明的任何函数都可以另外实现为类似函数的宏”
-
试试
(strncmp)(b, STRcommaLEN(c));。 -
感谢 cmets,@Bamar - 当我发现它不是错误并且他们不会对此采取任何措施时,我正准备将其报告为错误。
标签: gcc macros compiler-optimization c-preprocessor