Tag: c11

struct中间的可变长度数组 – 为什么这个C代码对gcc有效

使用VLA(可变长度数组)有一些奇怪的代码,它被gcc 4.6视为有效C(C99,C11): $ cat ac int main(int argc,char**argv) { struct args_t{ int a; int params[argc]; // << Wat? // VLA in the middle of some struct, between other fields int b; } args; args.b=0; for(args.a=0;args.a<argc;args.a++) { args.params[args.a]=argv[0][0]; args.b++; } return args.b; } 编译时此代码没有警告: $ gcc-4.6 -Wall -std=c99 ac && echo $? 0 $ ./a.out ; […]

为什么允许多次声明typedef标识符?

从C99标准来看,6.7(5): 声明指定一组标识符的解释和属性。 标识符的定义是该标识符的声明:对于对象,导致为该对象保留存储; 对于一个function,包括function体; 对于枚举常量或typedef名称,是标识符的(唯一)声明。 如果带有typedef标识符实际上是定义,那么为什么允许它们被多次声明? 例: int main() { typedef int x; typedef int x; } 以上程序编译没有错误。 这怎么可能? 我期待该程序给我一个多重定义错误。

int main(){}(没有“void”)在ISO C中是否有效且可移植?

C标准为托管实现指定了两种main的定义forms: int main(void) { /* … */ } 和 int main(int argc, char *argv[]) { /* … */ } 它可以以与上述“等效”的方式定义(例如,您可以更改参数名称,将int替换为定义为int的typedef名称,或将char *argv[]替换为char **argv )。 它也可以“以某种其他实现定义的方式”定义 – 这意味着如果实现记录它们int main(int argc, char *argv[], char *envp)是有效的。 “在其他一些实施定义的方式”条款不在1989/1990标准中; 它是由1999标准添加的(但早期标准允许扩展,因此实现仍然允许其他forms)。 我的问题是:鉴于当前(2011)ISO C标准,是表格的定义 int main() { /* … */ } 对所有托管实现有效且可移植? (请注意,我没有解决void main或在C ++中没有使用括号的int main() 。这只是ISO C中的int main(void)和int main()之间的区别。)

C11 _Generic:如何处理字符串文字?

使用C11中的_Genericfunction,您如何处理字符串文字? 例如: #include #define foo(x) _Generic((x), char *: puts(x)) int main() { foo(“Hello, world!”); return 0; } 在clang上给出了这个错误: controlling expression type ‘char [14]’ not compatible with any generic association type 用char[]替换char *给了我 error: type ‘char []’ in generic association incomplete 获得这个编译的唯一方法(据我所知)是: 将字符串文字转换为适当的类型。 这很丑陋(在我看来)首先打败了_Generic 。 使用char[14]作为类型说明符。 你一定是在开玩笑吧…… 我的假设是,当传递给_Generic时,数组会衰减到指针,但显然不是。 那么,如何将_Generic与字符串文字一起使用? 那是唯一的两种选择吗? 我在Debian上使用clang 3.2。 不幸的是,它是我可以访问的唯一支持此function的编译器,因此我无法判断它是否是编译器错误。

错误C4996:’scanf’:此函数或变量在c编程中可能不安全

我创建了一个小应用程序,通过使用带参数的用户定义函数来查找最大数量。 当我运行它时,它会显示此消息 错误1错误C4996:’scanf’:此函数或变量可能不安全。 请考虑使用scanf_s。 要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。 详细信息请参见在线帮助。 我该怎么做才能解决这个问题? 这是我的代码 #include void findtwonumber(void); void findthreenumber(void); int main() { int n; printf(“Fine Maximum of two number\n”); printf(“Fine Maximum of three number\n”); printf(“Choose one:”); scanf(“%d”, &n); if (n == 1) { findtwonumber(); } else if (n == 2) { findthreenumber(); } return 0; } void findtwonumber(void) { int a, […]

C99中那些奇怪的数组大小和是什么?

显然,以下函数原型在C99和C11中有效: void foo(int a[const *]); void bar(int a[static volatile 10]); 那些奇怪的下标符号* , static和CV限定符的目的是什么? 它们有助于区分静态类型数组和可变长度数组吗? 或者他们只是语法糖?

“可表示”在C11中意味着什么?

根据C11 WG14草案版本N1570 : 头文件声明了几个对字符分类和映射有用的函数。 在所有情况下,参数都是一个int ,其值应表示为unsigned char或者等于宏EOF的值。 如果参数具有任何其他值,则行为未定义。 是不确定的行为?: #include #include #include int main(void) { char c = CHAR_MIN; /* let assume that char is signed and CHAR_MIN < 0 */ return isspace(c) ? EXIT_FAILURE : EXIT_SUCCESS; } 标准是否允许将char传递给isspace() ( char为int )? 换句话说,转换为int后的unsigned char是否可表示为unsigned char ? 以下是wiktionary定义“可表示”的方式 : 能够代表。 char是否能够表示为unsigned char ? 是的 §6.2.6.1/ 4: […]

如何在编译时提取没有路径和后缀的源文件名?

同时使用带有-std = c11的gcc和带有-std = c ++ 14的g ++。 例如,对于名为src/dir/Hello.cxx的文件,它应该扩展为例如: const char basename[] = “Hello”; 要么 const char basename[] = getStaticBasename(__FILE__); 其中getStaticBasename()是一个宏(对于C源)或constexpr函数(对于C ++源),其结果为“Hello”。 我必须避免在运行时从__FILE__中拆分字符串,因为路径和后缀不能以任何方式编译到可执行文件中。 解决方案必须不依赖于诸如boost之类的大型库。 因为我没有makefile,所以在我的情况下不能使用这样的解决方案。 有人有解决方案吗? 编辑2015-07-02: 我对如何调用编译器和链接器没有影响(有时通过makefile,有时来自命令行,或某些IDE(Eclipse CDT托管make,Crossworks,Xcode等等)。所以解决方案只需要代码。 我的用例是为小型日志记录解决方案提供某种“通用区域标识符”。 应用程序代码(使用我的记录器)应仅#include 并且在稍后调用例如LOG_DEBUG(…)我将隐含地使用自动生成的“通用区域标识符”。 我目前的解决方案是应用程序代码必须声明一个JOE_LOG_FILE_REGION(Hello); (在#include ),它可以在其代码中放置LOG_DEBUG(…) 。

C11表达式中的赋值运算符排序

介绍 C11标准(ISO / IEC 9899:2011)在表达式中引入了新的副作用测序定义( 参见相关问题 )。 序列点概念已经在关系之前进行了序列补充,并且在关系之后 进行了 排序,这些关系现在是所有定义的基础。 第6.5节“表达式”,第2点说: 如果对标量对象的副作用相对于对同一标量对象的不同副作用或使用相同标量对象的值进行的值计算未进行排序,则行为未定义。 如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的。 稍后,第6.5.16节“分配操作员”,第3点指出: 在左右操作数的值计算之后,对更新左操作数的存储值的副作用进行排序。 对操作数的评估是不确定的。 问题 第一个引用的段落(6.5 / 2)由两个例子支持(与C99标准相同): 第一个例子 a[i++] = i; //! undefined a[i] = i; // allowed 这可以通过定义轻松解释: 如果相对于使用相同标量对象的值的(…)值计算,对标量对象的副作用未被排序,则行为未定义。 (6.5 / 2), 对操作数的评估是不确定的。 [在任务内](6.5.16 / 3)。 因此, i++ (LHS)的副作用与i (RHS)无关,这给出了未定义的行为。 第二个例子 i = ++i + 1; //! undefined i = i […]

GCC中的C11 ?

我正在尝试使用thread.h编译一些C11代码,但我不能。 我已经重新编译了GCC(现在运行4.6.2),我正在尝试使用gcc -std=c1x file.c -o file进行编译。 我可以用g ++(使用thread库)来做到这一点,但我不能在C中。是否thread.h没有包含在GCC发行版中的thread.h ?