我一直在浏览libgcc中定义的一些类型。 它们显然都映射到名为bogus_type的相同类型。 我找不到它的定义。 #define SItype bogus_type #define USItype bogus_type #define DItype bogus_type #define UDItype bogus_type #define SFtype bogus_type #define DFtype bogus_type 这种类型映射到什么? 它甚至是一个有效的类型或类似NULL东西?
在阅读了关于K&R书中结构的章节之后,我决定做一些测试来更好地理解它们,所以我写了这段代码: #include #include struct test func(char *c); struct test { int i ; int j ; char x[20]; }; main(void) { char c[20]; struct {int i ; int j ; char x[20];} a = {5 , 7 , “someString”} , b; c = func(“Another string”).x; printf(“%s\n” , c); } struct test func(char *c) { struct […]
以下代码: #include inline int myfunc (int x) { return x+3; } int main () { printf(“%d”, myfunc(2)); return 0; } 当我使用-std=gnu99标志(我正在使用gcc编译)时不编译。 这是它抛出的错误: gcc -std=gnu99 -c main.c -o main.o gcc -std=gnu99 main.o -o main main.o: In function `main’: main.c:(.text+0x15): undefined reference to `myfunc’ collect2: ld returned 1 exit status make: *** [main] Error 1 当省略-std=gnu99时,编译没有问题。 有没有人知道如果使用-std=gnu99 […]
以下程序具有未定义的行为: #include int main(void) { unsigned int x = -100; // This is fine, becomes UINT_MAX – 100 printf(“%d\n”, x); // This is undefined behavior. return 0; } C99 7.19.6.1p8状态%d需要一个int参数。 C99 7.19.6.1p9声明“如果任何参数不是相应转换规范的正确类型,则行为未定义 。” 但是,gcc -Wformat (包含在-Wall )不会抱怨上面的程序,为什么呢? 这是一个错误,还是故意遗漏? 从gcc手册页: -Wformat 检查对”printf”和”scanf”等的调用,以确保提供的参数具有适合指定格式字符串的类型,并确保格式字符串中指定的转换有意义
在gcc目标机器上,当想要编译共享库时,需要指定-fpic或-fPIC来使事情正常工作。 这是因为默认使用绝对寻址,它适用于完全控制自己的地址空间的可执行文件,但不适用于可以加载到可执行文件地址空间中任何位置的共享库。 然而,现代内核现在正在实现地址空间随机化,并且许多现代架构支持PC相对寻址。 这似乎使绝对寻址不可用(地址空间随机化)或不需要(PC相对寻址)。 我还注意到clang没有-fPIC选项,这使得我不再需要它。 那么-fpic现在是多余的,还是需要生成单独的.o文件,一个用于静态库,一个用于共享库?
考虑以下C语句: unsigned long x = 1; float a = -x; double b = -x; 我希望一元减项产生一个等于ULONG_MAX的无符号长值,a和b分别设置为ULONG_MAX的单精度和双精度表示。 这是我在32位Linux上使用gcc 4.4.7以及在64位Linux上使用Intel和PGI编译器获得的结果。 但是,对于64位Linux上的gcc(测试版本4.4.7,4.7.2和4.8.0,都带有-O0和-O2),双变量b具有预期值,但float a等于-1代替。 相比之下,以下语句将在我测试的所有编译器和系统上将a和b设置为ULONG_MAX的浮点表示: unsigned long x = 1; unsigned long y = -x; float a = y; double b = y; 如果我使用unsigned int而不是unsigned long,我也会在所有系统上得到预期的结果。 这是某种未定义的行为还是编译器错误?
我知道我可以放 #pragma GCC diagnostic ignored “” 到源文件的顶部以禁止与此特定源文件相关的警告。 但是,似乎有些名称不够具体。 例如, #pragma GCC diagnostic ignored “-Wwrite-strings” 不会阻止gcc(4.7.2)显示未给出确切名称的警告消息,相反,这些消息仅遵循[默认启用]。 我想我需要知道正确的警告名称,以便我可以在#pragma行中使用它们。 我试过了 -fdiagnostics-show-option, 但警告仍显示为[默认启用]。 有没有办法识别这些警告或者替代地抑制与特定源文件相关的警告? 非常感谢你!
我在C中编写了一个小型测试应用程序,并在我的Ubuntu 14.04上预装了GCC 4.8.4。 而我对表达式a=(b++);的事实感到困惑a=(b++); 行为方式与a=b++; 确实。 使用以下简单代码: #include #include int main(int argc, char* argv[]){ uint8_t a1, a2, b1=10, b2=10; a1=(b1++); a2=b2++; printf(“a1=%u, a2=%u, b1=%u, b2=%u.\n”, a1, a2, b1, b2); } gcc编译后的结果是a1=a2=10 ,而b1=b2=11 。 但是,我希望括号在其值分配给a1之前使b1递增。 即, a1应为11而a2等于10 。 有没有人对这个问题有所了解?
特别是在GCC上(即用GCC编译),以下两种方式有什么区别? struct foo1 { char a; int b; } __attribute__((__packed__, aligned(n) )); 和: #pragma pack(push, n) struct foo2 { char a; int b; }; #pragma pack(pop) 它们看起来表现不同 : foo1 f1; foo2 f2; int& i1 = f1.b; // ok int& i2 = f2.b; // cannot bind packed field ‘f2.foo2::b’ to ‘int&’ 为什么一个错误而另一个错误呢? 内存布局至少相同吗?
我认为GCC扩展__attribute__((cleanup))是一个好主意,至少在某些情况下,但我无法弄清楚如何以一种好的方式使用它。 我所做的一切看起来仍然很烦人。 我看到很多代码在做#define _cleanup_(x) __attribute__((cleanup(x))只是为了输入less,但有没有办法传递一个标准函数,如free或closedir , fclose等? 我看到我不能写: __attribute__((cleanup(free))) char *foo = malloc(10); 因为清理回调会收到char**指针,所以我必须总是这样写: static void free_char(char **ptr) { free(*ptr); } __cleanup__((free_char)) char *foo = malloc(10); 这非常烦人,最烦人的部分是为你需要的所有类型定义这样的清理函数,因为显然你不能只为void **定义它。 避免这些事情的最佳方法是什么?