Tag: c99

使用sscanf将C字符串拆分为标记

我试图将一个字符串拆分成令牌,但有点递归。 我想解析: “content=0&website=Google” 这样我就可以拿出参数和值了。 如果我尝试strtok我最终会破坏我要解析两次的字符串。 所以我试过了 char *contents = “content=0&website=Google” char arg[100]; char value[100]; sscanf(contents, “%s&%s”, arg, value); 作为第一遍,希望再次解析arg ,但它失败了, arg包含整个字符串。 我尝试使用”%s\&%s”思考并且是一个保留字,但没有运气。 救命! 编辑: 这是我的strtok hack: static void readParams(char * string, char * param, char * value) { printf(“This is the string %s\n”,string); char * splitted = strtok (string,”=”); while (splitted != NULL) { printf(“This […]

未定义的行为:尝试访问函数调用的结果时

以下编译并打印“string”作为输出。 #include struct S { int x; char c[7]; }; struct S bar() { struct S s = {42, “string”}; return s; } int main() { printf(“%s”, bar().c); } 显然,这似乎引发了一个未定义的行为 C99 6.5.2.2/5如果尝试修改函数调用的结果或在下一个序列点之后访问它,则行为未定义。 我不明白它在哪里说“下一个序列点”。 这里发生了什么?

桌面操作系统上的C编译器使用多少个内存页来检测堆栈溢出?

这个问题与C99中的可变长度数组有关但不同。 答案指出,在堆栈中分配可变长度数组(或者只是固定大小的大数组)的一个危险是分配可能会无声地失败,而不是调用malloc ,后者明确告诉调用者分配是否成功。 现代非嵌入式编译平台使用无效的内存区域来检测一些堆栈溢出,而无需额外成本(检查只是MMU已经免费进行的检查)。 这不能保证100%免受上述问题的影响,因为非常大的本地数组可能导致堆栈指针跳过无效区域。 是否有人知道通常为此检测分配了多少页? 我想这至少是4KiB,但它可能会更多。 这是由编译器或操作系统做出的选择,在任何一种情况下,有没有办法改变它?

Peterson Lock算法的测试实现?

有谁知道Peterson的锁定算法在C中的良好/正确实现? 我似乎无法找到这个。 谢谢。

哪个C99编译器(Clang vs. GCC)更接近const结构域的标准?

我有这样的代码: $ cat test.c #include typedef struct { const int x; } SX; static SX mksx(void) { return (SX) { .x = 10 }; } void fn(void) { SX sx; while((sx = mksx()).x != 20) { printf(“stupid code!”); } } 关于其正确性的2条意见: $ for i in gcc clang; do echo “$i SAYS:”; $i -c -std=c99 -pedantic […]

初始化变量并在声明后立即赋值给它是否有区别?

假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异? 初始化方法 : int x = 2; 作业方式 : int x; x = 2; 我使用GCC输出为这两种不同方法生成的程序集,并且两者都产生了一条机器指令: movl $2, 12(%esp) 该指令只是将x变量保存的内存设置为值2 。 GCC可能正在优化这一点,因为它可以识别操作的最终结果; 但我认为这是解释这两个版本的唯一方法。 我的理由是两个版本都做同样的事情:将内存的一部分设置为特定值。 那么,如果生成的机器代码相同,那么为什么通常会在术语“ 初始化 ”和“ 赋值 ”之间进行区分? 术语“ 初始化 ”是否纯粹用于区分具有特定值的变量,这些变量具有在内存中留下任何垃圾值的那些(非初始化)变量?

如何在C99运行时计算可变长度数组的大小?

在C89中,数组的长度在编译时是已知的。 但在C99中,对于可变长度数组,数组的长度在运行时可能是未知的。 那怎么计算呢? 为什么不能以相同的方式计算动态分配的数组的长度?

C89中的可变长度数组?

我已经读过C89不支持可变长度数组,但以下实验似乎反驳了: #include int main() { int x; printf(“Enter a number: “); scanf(“%d”, &x); int a[x]; a[0] = 1; // … return 0; } 当我这样编译时(假设filename是va_test.c ): gcc va_test.c -std=c89 -o va_test 有用… 我错过了什么? 🙂

C99的预处理器中的static_if

是否可以在C99中实现static_if? #define STATIC_IF(COND, …) \ if (COND) MACRO1(__VA_ARGS__); \ else MACRO2(__VA_ARGS__); 我怎样才能在这里正确实现STATIC_IF(…) ? 根据COND ,参数应该传递给MACRO1或MACRO2 ,但两个宏的参数看起来不同。 COND是静态可测试的,类似sizeof (…) > 42 。 #if COND然后#define STATIC_IF MACRO1 …对我的用例不起作用。 我不能使用编译器特定的解决方案。

内核的“container_of” – 任何使ISO符合标准的方法吗?

在查看Linux内核的双向链接循环列表的实现时,我发现了以下宏: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr – offsetof(type,member) );}) 这种方式的工作方式是它返回指向结构的指针,只给出其中一个成员的地址: struct blabla { int value; struct list_head *list; } 因此,只有指向列表的指针,您才能获得指向blabla(并获得“value”)的指针。 对于我的问题,我如何使其尽可能便携(符合C89 / C99的最佳情况?)。 由于使用了typeof(),这只是gcc。 这是我到目前为止所得到的: #define container_of(ptr, type, member) ( \ (type *) (char *)(ptr)-offsetof(type,member)\ ) 这个片段是否符合ISO标准(因此应该能够在任何符合标准的编译器上编译)?