Tag: c11

scanf_s函数的标头

在回答这个问题时,我在Ideone上编译了代码并得到了这个错误 implicit declaration of function ‘scanf_s’ [-Wimplicit-function-declaration] 是不是stdio.h是scanf_s的头?

如何将变量声明为本地可移植的线程?

C11引入了_Thread_local存储类说明符,可以与static和extern存储类说明符结合使用,将变量声明为线程局部。 GNU C编译器套件使用相同的语义实现存储类说明__thread 。 不幸的是我没有找到任何实际实现_Thread_local关键字的编译器(我尝试过gcc,clang和SUN studio)。 我目前使用以下构造来声明关键字thread_local : /* gcc doesn’t know _Thread_local from C11 yet */ #ifdef __GNUC__ # define thread_local __thread #elif __STDC_VERSION__ >= 201112L # define thread_local _Thread_local #else # error Don’t know how to define thread_local #endif 我知道这可能不适用于MSVC和其他编译器。 任何人都可以建议我一个更好的方法来声明thread_local ,使其在尽可能多的编译器中工作吗? 编辑 Christoph建议Microsoft Visual C允许__declspec(thread) 。 这是更新的宏定义: /* gcc doesn’t know _Thread_local […]

有没有办法在单个翻译单元中使用GCC __attribute __((noreturn))和?

在C11中,有一个关键字_Noreturn ,它是一个函数说明符(如inline is),表示函数没有返回 – 它调用exit()或等效函数。 还有一个标题 ,其完整定义是: 7.23 _Noreturn ¶1标题定义宏 noreturn 它扩展到_Noreturn 。 在GNU C(GCC)中,有一个属性__attribute__((noreturn)) ,它基本上执行相同的工作。 一个区别是__attribute__((noreturn))可以出现在函数声明__attribute__((noreturn))之前或之后: extern __attribute__((noreturn)) void err_error(const char *format, …); extern void err_error(const char *format, …) __attribute__((noreturn)); 问题是,如果在转换单元(TU)中包含 ,则__attribute__((noreturn))任何后续使用都会映射到__attribute__((_Noreturn)) ,这会导致编译失败,因为属性_Noreturn无法识别(即使关键字被识别为关键字)。 也就是说,据我所知,你不能同时使用这两个系统。 有什么方法可以解决这个问题,除了: 使用该属性使用的所有代码的大爆炸,或 使用不完全优雅的_Noreturn关键字? 您可以通过测试__STDC_VERSION__ >= 201112L来检测C11 – 该值由技术勘误1指定,因为标准意外地保留了未完全指定的值: __STDC_VERSION__整数常量201ymmL 。 178) 178)该宏未在ISO / IEC 9899:1990中规定,在ISO / IEC 9899:1990 / Amd.1:1995中指定为199409L,在ISO […]

GCC 4.8中的?

我想利用C11标准提供的新primefaces操作。 但是,尝试#include适当的头文件给了我这个: csort-par.c:5:23: fatal error: stdatomic.h: No such file or directory #include http://gcc.gnu.org/wiki/C11Status上的文档似乎说自从GCC 4.7以来提供了头文件…我错过了什么? __STDC_NO_ATOMICS__未定义。 gcc –version如下: gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 Copyright (C) 2013 Free Software Foundation, Inc. 我确认__STDC_NO_ATOMICS__没有定义如下: #ifdef __STDC_NO_ATOMICS__ #error yes #else #error no #endif 收益率: csort-par.c:10:2: error: #error no #error no 编辑:感谢您的快速回复。 如果有人在谷歌遇到同样的问题而绊倒了这个问题,那么这是暂时的解决方案,直到他们发布GCC 4.9: UNIX便携式primefaces操作

C标准malloc’ing字符的潜在问题

当我在这里回答对我的另一个答案的评论时,我发现我认为可能是C标准中的一个漏洞(c1x,我没有检查过早期的那些,是的,我知道我不可能单独在所有星球中居民在标准中发现了一个错误)。 信息如下: 第6.5.3.4节(“sizeof运算符”)第2节规定”The sizeof operator yields the size (in bytes) of its operand” 。 该部分的第3段指出: “When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1” 。 第7.20.3.3节描述了void *malloc(size_t sz)但它说的是”The malloc function allocates space for an object whose size is specified by size […]

序列点和副作用:C11的安静变化?

C99§6.5 表达式 (1)表达式是操作符和操作数的序列,其指定值的计算,或指定对象或函数,或者生成副作用,或执行其组合。 (2)在前一个和下一个序列点之间,一个对象的存储值最多只能通过表达式的计算来修改一次。 72)此外,先前的值应该是只读的,以确定要存储的值。 73) 用脚注 72)浮点状态标志不是对象,可以在表达式中多次设置。 73)此段落呈现未定义的语句表达式,如 i = ++i + 1; a[i++] = i; 同时允许 i = i + 1; a[i] = i; C11§6.5改为((1)的文本有附录): (1)[…]运算符的操作数的值计算在运算符的结果的值计算之前被排序。 (2)如果对标量对象的副作用相对于对同一标量对象的不同副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义。 如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的。 84) 其中C11中的脚注84与C99中的73相同。 我有点困惑……我把C11(2)看作是“[…](对同一个标量对象的不同副作用)或(使用相同标量对象的值进行值计算)[…]”甚至不允许foo = ++i (有副作用,我们根据更改的对象使用值)。 不过,我不是母语人士,所以如果能告诉我这句话应该如何“解析”会更好。 我理解C99,但我不太明白C11的措辞。 无论如何,实际问题:这是从C99到C11的变化,还是这些措辞相当? 如果是这样,为什么它会被改变? 如果没有,有人可以给出一个表达式的例子,这个表达式在C99中是UB但在C11中不是,反之亦然?

空值返回函数g可以返回f(); 当f返回void?

请考虑以下代码段: void f(void); void g(…) { … return f(); … } 这是return f(); 根据C11有效吗? 我并不主张使用这种模式:如果它起作用,它显然等同于f(); return; f(); return; ( return;如果它在函数g()的末尾,则本身将是多余的)。 我在C程序的静态分析的上下文中问这个问题,其中C代码已经由其他人编写,问题是根据标准判断它是否有效。 我认为C11 6.8.6.4:1意味着它是非标准的并且应该被静态拒绝。 是否有可能以不同的方式解释它(我在实际和其他高质量的源代码中找到了这种模式)? 约束 带有表达式的return语句不应出现在返回类型为void的函数中。 不带表达式的return语句只能出现在返回类型为void的函数中。

C11的__STDC_VERSION__值是多少?

我知道编译器使用__STDC__来表示编译器是标准C,并且从那里,您可以使用__STDC_VERSION__来确定您正在使用的标准级别 。 我也知道C90没有价值,C90修正案1有199401L而C99有199901L 。 最新的C1x草案我简单地说它是201ymmL ,我假设它在最终标准中的价值不那么“模糊”。 我的猜测是,自从C11被批准以来,它将是201112L ,但我想确定一下。 我以为我可以尝试使用gcc -std=c1x但我正在运行的gcc版本还不支持。 有谁知道实际价值是多少?

比特域的类型是什么?

我在C标准中找不到指定的任何地方。 例如,在 struct { signed int x:1; } foo; 是foo.x是int类型的左值还是其他什么? 因为你不能在其中存储int类型的任何值,只有0或-1,但是我找不到任何可以为它分配不同类型的语言,因此它似乎不自然地成为int类型的左值。 当然,在大多数表达式中使用它,无论如何它都会被提升为int ,但是实际的类型在C11中与_Generic有所不同,我在标准中找不到任何关于bitfields如何与_Generic交互的语言。

为什么编译器在尝试修改char *字符串文字时没有检测到并产生错误?

假设以下两段代码: char *c = “hello world”; c[1] = ‘y’; 上面的那个不起作用。 char c[] = “hello world”; c[1] = ‘y’; 这一个。 关于第一个,我理解字符串“hello world”可能存储在只读存储器部分中,因此无法更改。 然而,第二个在堆栈上创建一个字符数组,因此可以进行修改。 我的问题是 – 为什么编译器不会检测到第一类错误? 为什么不是C标准的一部分? 这有什么特别的原因吗?