Tag: gcc

为什么stddef.h不在/ usr / include中?

我编译了gnu标准库并将其安装在$GLIBC_INST 。 现在,我尝试编译一个非常简单的程序(只使用一个#include: #include ): gcc –nostdinc -I$GLIBC_INST/include foo.c 编译(预处理器?)告诉我,它没有找到stddef.h 。 事实上, $GLIBC_INST/include没有(在/usr/include也没有)。 但是,我在/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include找到了一个stddef.h 。 为什么该文件不在/usr/include ? 我认为它属于标准c库,应该安装在$GLIBC_INST/include 。 如果没有stddef.h我怎么能用新安装的标准库编译我的foo.c ? 编辑:澄清 我觉得这个问题的标题不是最优的。 正如一些答案所指出的那样, stddef.h不需要在/usr/include (或者$GLIBC_INST/include ,就此而言)。 我明白这一点。 但是我想知道当我想使用$GLIBC_INST时我该怎么$GLIBC_INST 。 我似乎很明显(虽然我可能在这里错了)我需要使用–nostdinc调用gcc以便不使用系统安装的头文件。 这需要我使用-I$GLIB_INST/include 。 这对我来说很清楚。 然而,我还不清楚的是:当我还添加-I/usr/lib/gcc/x86…./include ,我怎么能确定我确实拥有新编译的glibc的最新头文件?

如何让GCC在编译时评估函数?

我正在考虑以下问题:我想用一个使用某种查找表的程序编程一个微控制器(比如一个AVR mega类型)。 第一次尝试是将表定位在一个单独的文件中,并使用任何其他脚本语言/程序/创建它。在这种情况下,为C创建必要的源文件需要付出相当大的努力。 我现在的想法是使用预处理器和编译器来处理事情。 我尝试用一​​个正弦值表来实现它(仅作为示例): #include #include #define S1(i,n) ((uint8_t) sin(M_PI*(i)/n*255)) #define S4(i,n) S1(i,n), S1(i+1,n), S1(i+2,n), S1(i+3,n) uint8_t lut[] = {S4(0,4)}; void main() { uint8_t val, i; for(i=0; i<4; i++) { val = lut[i]; } } 如果我编译这段代码,我会得到有关sin函数的警告。 在程序集中,在.data部分中没有任何内容。 如果我只是删除第三行中的sin ,我得到程序集中的数据。 显然,所有信息都可以在编译时获得。 你能否告诉我是否有办法实现我的目的:编译器计算尽可能多的离线值? 或者是使用外部脚本/程序/ …来计算表条目并将它们添加到一个单独的文件中的最佳方式,该文件只是#include d?

C:为什么用%s打印null char会打印“(null)”?

为什么用%s打印空字符(’\ 0’,0)实际打印“(null)”字符串? 喜欢这段代码: char null_byte = ‘\0’; printf(“null_byte: %s\n”, null_byte); …打印: null_byte: (null) …它甚至在Valgrind下运行没有错误,我得到的是编译器警告warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat] (注意:我在32位Ubuntu上使用gcc 4.6.3)

Gcc使用sqrt而不包括math.h

任何人都知道为什么这个c程序编译并使用math.h的sqrt? 这将输出2.236068 main.c中 #include #include “math_utils.h” int main(void){ printf(“%f\n”, sqrt(5)); return 0; } math_utils.h #ifndef MATH_UTILS_Hs #define MATH_UTILS_Hs double sqrt(double number){ return number + 5; } #endif // MATH_UTILS_Hs 我目前正在Windows上使用mingw GCC

‘noreturn’function确实会回归

当我编译下面的C程序时,我收到这个警告: ‘noreturn’ function does return 。 这是function: void hello(void){ int i; i=1; } 为什么会这样? 对此函数的所有调用都是hello(); 编辑:完整的错误输出: home.c: In function ‘hello’: hhme.c:838:7: error: variable ‘i’ set but not used [-Werror=unused-but-set-variable] home.c:840:1: error: ‘noreturn’ function does return [-Werror] cc1: all warnings being treated as errors make: *** [home.o] Error 1

优雅而安全的方法来确定架构是32位还是64位

正如标题所说,有没有任何优雅和安全的方法来确定架构是32位还是64位。 通过优雅,您可以想到精确,正确,简短,干净和智能的方式。 安全,从标准,C89 / C99和操作系统独立性的角度考虑安全。

关于`({});`的更多信息?

我注意到有时,C宏被写成这样的东西: #define foo(bar) ({ ++bar; }) 经过一些实验,我发现: ({}); 会编译,但什么都不做。 (正如所料。) 离开; off会导致语法错误。 这样做的副作用是确保foo()看起来像代码中的函数。 (虽然,如果关闭分号,错误对诊断问题不是很有用!) return ({}); 抱怨虚假值不被忽略,就像我试图使用void函数一样。 这只是为了让开发人员在他们的宏中添加分号,还是有另一个目的? 我已经尝试过谷歌,但是标点符号失败了。 这有名字吗?

宏定义中双重否定的目的是什么,如(!!(expr))?

可能重复: C ++代码中的双重否定。 我正在阅读代码库,并找到这样的东西: #define uassert(msgid, msg, expr) (void)((!!(expr))||(uasserted(msgid, msg), 0)) 我无法弄清楚为什么(!!(expr))而不是单个(expr) 。 无论如何,双重否定意味着积极,不是吗? 我错过了什么吗?

为什么>> 24导致-Wconversion但是>> 23不?

这是代码: #include unsigned char f(uint32_t RGBA) { return (RGBA>>24) & 0xFF; } 当使用-Wconversion编译时,它会导致“警告:从’uint32_t {aka unsigned int}’转换为’unsigned char”可能会改变其值[-Wconversion]”。 如果我将移位值降低到23或更低,则警告消失。 我查看了C99标准,我不明白这里发生了什么。 如果我删除&运算符,则总是发出警告,这可能是好的,因为表达式(在整数提升之后)的结果大于unsigned char 。 我唯一的想法是,对于较小的class次省略警告只是因为gcc是聪明的并且无论如何都看到结果是8位,因为标准不会使这成为特殊情况。 我在这儿吗? 为什么class次价值很重要? 这是GCC的错误吗? Clang似乎没有为任何class次值发出警告。 我在64位Linux系统上使用GCC 5.3.1。

在C中使用非标准的数组声明

我遇到了以下代码,它以非标准的方式在C中声明了char *数组: /* Message Type description array */ char *msgType[M_LAST_MSG] = { [M_INIT_MSG] “Init”, [M_RESET_MSG] “Serdes Reset” }; M_INIT_MSG , M_RESET_MSG和M_LAST_MSG是枚举,其对应值为0,1和2.根据正式的C文档,此数组中的变量是字符串(文字),那么以这种方式使用这些枚举的目的是什么呢?备份文件? 用ARM gcc编译器编译gcc-arm-none-eabi 。