Tag: c99

长度为0的可变长度数组?

在C中,通常不允许数组的大小为0(除非我使用一个或其他编译器端扩展)。 OTOH,有长度可能为0的VLA。 他们被允许吗? 我在谈论以下代码: void send_stuff() { char data[4 * !!flag1 + 2 * !!flag2]; uint8_t cursor = 0; if (flag1) { // fill 4 bytes of data into &data[cursor] cursor += 4; } if (flag2) { // fill 2 bytes of data into &data[cursor] cursor += 2; } } 结果是一个长度为0,2,4或6的data数组,具体取决于标志的组合。 现在的问题是:对于数组结果长度为0的情况,这个有效代码是什么?

是使用未定义的任何不确定值还是仅存储在具有自动存储的对象中的值?

根据C99 J.2,在以下情况下行为未定义: 具有自动存储持续时间的对象的值在不确定时使用 那么对象具有不确定值的所有其他情况呢? 如果我们使用它们,我们是否也总是调用UB? 或者我们只在它们包含陷阱表示时调用UB? 例子包括: 使用malloc分配的对象的值(7.20.3.3p2) [存储在非自动存储器中]调用fclose后的FILE* (7.19.3p4) [存储在非自动存储器中]一个指针后free调用它(6.2.4p2) …等等。 我已将C99用于我的参考文献,但您可以在答案中自由引用C99或C11。

MinGW Compiler for Windows,使用GCC,C99和GNU99

我正在使用适用于Windows的MinGW编译器。 我在C中制作了一些程序。我读到的大部分文章似乎都已经过时了…最后我读到C99在GCC中是不完整的,这仍然是真的吗? 我真正的问题是设置C99和GNU99之间的跨平台兼容性……我应该避免使用GNU99设置和它的扩展,只是坚持使用C99? 我是这个MinGW编译器集的新手,因为我一直使用Visual Studio并决定尝试新的东西……现在我正在使用这些设置编译… -march=native -O3 -std=gnu99 我是否应该为制作C程序以及使用此编译器制作C ++程序而输入任何推荐的编译器命令? 我想制作一个与Windows,Mac和Linux兼容的简单程序,但首先是大多数Windows。

复合文字有没有办法在c99中有可变长度?

我知道通过正常声明数组,可以在运行时确定长度的数组: char buf[len]; 而且我知道我可以将数组声明为复合litral并将其分配给中间的指针: char *buf; …. buf = (char[5]) {0}; 但是,将两者结合起来并不起作用(标准不允许)。 我的问题是:有没有办法实现以下代码的效果? (注释len ) char *buf; …. buf = (char[len]) {0}; 谢谢。

C,Open MPI:从调用到MPI_Finalize()的分段错误。 Segfault并不总是会发生,特别是在进程数量较少的情况下

我正在编写一个简单的代码来学习如何定义MPI_Datatype并将其与MPI_Gatherv结合使用。 我想确保我可以在一个进程上组合可变长度,动态分配的结构化数据数组,这似乎工作正常,直到我调用MPI_Finalize()。 我已经确认这是通过使用print语句和Eclipse PTP调试器(后端是gdb-mi)来解决问题的地方。 我的主要问题是,如何摆脱分段错误? 每次运行代码时都不会发生段错误。 例如,2或3个进程没有发生,但是当我运行大约4个或更多进程时,往往会定期发生。 此外,当我使用valgrind运行此代码时,不会发生分段错误。 但是,我确实从valgrind获得了错误消息,尽管我使用MPI函数时很难理解输出,即使有大量的目标抑制。 我也担心如果我使用更多的抑制,我会沉默一个有用的错误信息。 我使用这些标志编译正常代码,所以我在两种情况下都使用C99标准:-ansi -pedantic -Wall -O2 -march = barcelona -fomit-frame-pointer -std = c99和调试代码:-ansi -pedantic -std = c99 -Wall -g 两者都使用gcc 4.4 mpicc编译器,并使用Red Hat Linux和Open MPI v1.4.5在集群上运行。 如果我遗漏了其他重要的信息,请告诉我。 这是代码,并提前感谢: //#include #include #include #include #include //#include #include “mpi.h” #define FULL_PROGRAM 1 struct CD{ int int_ID; double dbl_ID; }; int […]

是否有推荐的整数类型来存储标准C中的函数指针

C99标准有uintptr_t ,一种推荐的整数类型,用于将数据指针(指向对象的指针)转换为,但是我找不到用于存储函数指针的等效整数类型。 我忽略了吗? 特定编译器可以定义这样的类型,即使它不在标准中,但编译器更可能声明函数指针可以存储在(比如说) uint64_t不是定义新类型。 另一个不同之处在于,对数据指针执行整数运算是有意义的,而不是在函数指针上。 一个常见的习语是(int*)(((uintptr_t)p + 15) & ~(uintptr_t)15)但是没有理由将这个习语应用于函数指针。

C预处理器语句是否是C语言的一部分?

我记得我的一位教授在C课程中的主张。 他说,# #define预处理器命令使程序员能够创建一个常量,以便在以后的代码中使用,并且该命令是C语言的一部分 。 /* Is this truly C code? */ #define FOO 42 由于这是一个介绍性的编程类,我怀疑他只是简化了源文件和编译器之间的关系,但我希望validation我的理解。 预处理器语句是否完全独立于C语言(取决于所使用的特定编译器)还是在C99标准中明确描述? 出于好奇,K&R曾经提到过预处理器宏吗?

在c99中使用__thread

我想使用__thread存储类将一些变量定义为特定于线程的。 但是三个问题让我犹豫不决: 它真的是c99的标准吗? 或者更重要的是,编译器支持有多好? 变量是否会在每个线程中初始化? 非multithreading程序是否将它们视为普通的全局变量?

枚举是否是位域实现定义的类型?

我试图更好地理解C99标准,但现在我对使用枚举作为结构中的位域以及它们被视为int还是实现定义类型感到困惑。 在查看C99的最终草案时,我找到了6.7.2.1段。 4 位字段的类型应为_Bool , signed int , unsigned int或其他实现定义类型的限定或非限定版本。 和6.7.2.2段。 4 每个枚举类型应与char ,有符号整数类型或无符号整数类型兼容。 类型的选择是实现定义的,但应能够表示枚举的所有成员的值。 … 所以我尝试使用这个简单的源代码 enum e { E0, E1 }; struct s { enum e bitfield : 4; }; 我可以用gcc-5.0和clang-3.5使用-std=c99 -Wall -Wextra -pedantic编译这个没有警告但是我用gcc-4.8得到以下警告 warning: type of bit-field ‘bitfield’ is a GCC extension 这里开始混乱。 枚举是否将位域视为int或实现定义的类型? 这是GCC-4.8中的错误还是他们改变了对标准的解释? 与其他C99编译器一起使用是否安全?

printf转换规范的大小限制

printf转换规范是%后跟标志,宽度,精度,长度修改器和转换说明符。 转换规范的大小是否有实际限制? 即%s是2个字符长,而%08.2f是6个字符长。 我的问题是,根据C99标准,可以创建的格式字符串中的最大单一规范的长度是多少?