Tag:

为什么GCC保持空function?

在大多数情况下,如果我想在C中创建一个可选function,我只需创建两个这样的函数: #ifdef OPTIONAL_SOMETHING void do_something(int n, const char *s) { while (n–) { printf(“%s”, s); } /* …You might get the point, really do something… */ } #else void do_something(int n, const char *s) { /* Empty body */ } #endif 因此,如果符号未定义 – 禁用该function时 – 将空函数编译到可执行文件中。 深入研究汇编列表,似乎GCC 在禁用优化时编译并调用空函数。 如果启用了优化 ,也使用了-O2和-O3 ,它只编译必要的堆栈处理代码,但它会优化调用指令。 总而言之,它保留了function。 大约相同的情况适用于非空但未使用的方法。 它应该简单地扔掉整个东西,但事实并非如此。 为什么它是默认行为? […]

宏评估订单

可能重复: 宏中的#和## 为什么第二个printf的输出是f(1,2)什么是宏的评估顺序? #include #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf(“%s\n”,h(f(1,2))); printf(“%s\n”,g(f(1,2))); return 0; } output 12 f(1,2)

是否有预处理器宏来检测跨平台的C99?

C ++有一个__cplusplus预处理器定义,可以让你检测版本。 C有什么相似之处吗? 我希望它可以在XCode,GCC和Visual Studio版本中移植。

循环通过宏Varargs值

如果我定义一些宏: #define foo(args…) ({/*do something*/}) 有没有办法实际循环args而不是传递给另一个函数? 就像是 #define foo(args…) \ { \ for (int i = 0; i < sizeof(args); ++i) { \ /*do something with args[i]*/ \ } \ }

宏定义ARRAY_SIZE

在Google V8项目中读取globals.h时,我遇到了以下宏定义。 // The expression ARRAY_SIZE(a) is a compile-time constant of type // size_t which represents the number of elements of the given // array. You should only use ARRAY_SIZE on statically allocated // arrays. #define ARRAY_SIZE(a) \ ((sizeof(a) / sizeof(*(a))) / \ static_cast(!(sizeof(a) % sizeof(*(a))))) 我的问题是后一部分: static_cast(!(sizeof(a) % sizeof(*(a))))) 。 我想到的一件事是:由于后一部分将始终求值为1 ,其类型为size_t ,因此整个表达式将被提升为size_t 。 […]

是否可以在#define中使用if语句?

我正在尝试使用以下公式制作一个宏: (a^2/(a+b))*b ,我想确保没有除以零。 #define SUM_A( x, y ) if( x == 0 || y == 0) { 0 } else { ( ( ( x * x ) / ( ( x ) + ( y ) ) ) * ( y ) )} 然后我在main中调用宏: float a = 40, b = 10, result; result = […]

为GCC运行“轻型”预处理器

有没有办法运行GCC预处理器,但仅适用于用户定义的宏? 我有一些单行和一些#ifdef等条件,我想看看我的代码在扩展时的样子。 实际上,包括扩展,我的fprintf(stderr)变成fprintf(((__getreeent())->_stderr)等。

使用MACROS禁用function

在互联网上搜索了相当多的解决方案后,我决定在这里询问我的解决方案是否正常。 我正在尝试编写一个简单的模块化C日志库,旨在简化禁用,并特别帮助博士生和研究人员调试算法,尽可能减少日志记录系统的影响。 我的问题是我希望库的用户可以在编译时禁用日志系统,生成一个可执行文件,其中记录器的成本为0。 C代码看起来像这样: … logger_t * logger; result = logger_init(logger); if(result == -1) {…} … 这将简单地初始化记录器。 寻找一个示例代码我检查了assert.h头,但是在我的情况下,soulution会产生一个警告列表。 实际上,如果使用宏将logger_init()替换为0,则会导致变量logger从未使用过。 出于这个原因,我决定使用这种方法: int logger_init(logger_t *logger); #ifndef NLOG /* NLOG not defined -> enable logging */ int logger_init(logger_t *logger) { … } #else /* NLOG defined –> the logging system must be disabled */ #define logger_init(logger) (int)((logger = […]

C ++宏记录每行代码

在我最近与我的经理的一次讨论中,他提到他的一位前客户使用C ++宏来记录每行代码的信息。 他们所要做的就是在开始运行之前启用环境变量。 (当然,环境变量仅在测试床中启用。 日志中提到了使用的变量及其对应的值。 例如,对于该行: a = a + b; 日志会说: “a = a + b; (a = 5 + 3)” 就个人而言,我不确定这是否可能,但他非常确定这已经存在,尽管他不记得代码的具体细节。 所以,这是(显而易见的)问题:这可能吗? 你能提供这个代码吗?

如何编写可在C ++程序中使用的C头文件?

可能重复: 如何检查(通过预处理器)C源文件是否被编译为C ++代码 我正在尝试找到一个标准宏来测试头文件是编译为C还是C ++。 这样做的目的是标题可以包含在C或C ++代码中,并且必须根据具体情况略有不同。 特别: 在C中,我需要这个代码: extern size_t insert (const char*); 在C ++中,我需要这个代码: extern “C” size_t insert (const char*); 另外,有没有办法避免在标题中的每个声明周围放置#ifdef?