Tag: c11

结构成员与_Alignas对齐

我想知道以下内容:C11中新的_Alignas对齐说明符适用于结构成员吗? 我总是假设那么多,但是对N1570公共草案的全面阅读似乎表明, 对齐指定符不能出现在说明符限定符列表中,如果它被支持的话,这是我期望的那样。 。 我已经阅读了几次语法,但无法弄清楚如何在结构成员声明中允许_Alignas 。 但是,在我看来,该标准的意图是_Alignas应该适用于结构成员,因为_Alignas (第6.7.5节)中的段落声明“在[…]的声明中不应指明对齐属性。 ]一个比特字段“。 鉴于术语“位字段”在第6.7.2.1节中定义为结构成员(精确措辞:“这样的成员称为位字段 ”),我总是将该句子解释为隐含意味着对齐说明符是允许非位字段成员。 检查现有实现表明,Clang 3.0和GCC 4.7都支持结构成员上的-pedantic而不会抱怨(使用-pedantic )。 Clang源代码从N1570再现相同的语法,除了Parser::ParseSpecifierQualifierList允许对齐说明符; 该函数确实包含一个TODO元素,其内容如下: /// TODO: diagnose attribute-specifiers and alignment-specifiers. GCC C解析器代码看似相似,即使它引用了标准语法,它允许在说明符限定符列表中使用对齐说明符。 我还检查了已知缺陷列表,以及comp.lang.c和comp.std.c,以查看是否已在那里提出主题,但似乎并非如此。 因此,我的问题是:结构成员应该允许对齐说明符吗? 编辑:相关的语法规则是: // Compare this… (6.7) declaration-specifiers: storage-class-specifier declaration-specifiers_opt type-specifier declaration-specifiers_opt type-qualifier declaration-specifiers_opt function-specifier declaration-specifiers_opt // This seems to be the only place that mentions // alignment-specifier on the […]

C11 Unicode支持

我正在写一些类似于atoi()或strtoll()字符串转换函数。 我想要包含一个我的函数版本,它接受char16_t *或char32_t *而不仅仅是char *或wchar_t *。 我的function很好,但正如我写的那样,我意识到我不明白char16_t或char32_t是什么。 我知道标准只要求它们分别是至少16位或32位的整数类型,但暗示它们是UTF-16或UTF-32。 我也知道标准定义了几个函数,但它们没有包含任何* get或* put函数(就像它们在C99中的wchar.h中添加时那样)。 所以我想知道:他们期望我用char16_t和char32_t做什么?

为什么C类通用表达式不能与C ++兼容?

我似乎记得听到几个可靠来源(即委员会成员在非官方渠道中发言)的模糊评论,C类通用表达式不会被添加到C ++中,因为它们不可能。 据我所知,与C ++模板和重载相比,类型generics表达式非常有限,但是没有潜在的交互需要被定义为特殊情况。 类型通用表达式由控制表达式和类型与子表达式之间的一系列“关联”组成。 基于控制表达式的静态类型和为子表达式列出的类型来选择子表达式,并且替换它代替TGE。 匹配基于类型兼容性的C概念,据我所知,它等同于在单定义规则(ODR)下具有extern链接的类型的C ++标识。 如果派生类控制表达式在C ++中选择基类关联会很好,但由于C没有inheritance,因此交叉兼容性不需要这样的精确性。 这被认为是一个绊脚石吗? 编辑:至于更具体的细节,C11已经提供了保留所选子表达式的值类别(左值),并且似乎要求TGE是一个常量表达式(无论什么类别),只要它的所有操作数都是,包括控制表达。 这可能是C语言缺陷。 在任何情况下,C ++ 14根据可能被评估的内容定义常量表达式,并且TGE规范已经表明未选择的子表达式未被评估。 关键在于TGE操作原理看起来很简单,可以移植而不会在以后造成麻烦。 至于为什么 C ++ TGE会有用,除了最大化C和C ++的交集之外,它们可以用来实现static_if ,没有极具争议的条件声明function。 我不是static_if的支持者,但“有那个。” template void f( tq ) { auto is_big = _Generic( std::integral_constant= 4 >(), std::true_type: std::string( “whatta whopper” ), std::false_type: “no big deal” ); auto message = _Generic( t, double: “double”, int: […]

如何使用函数指针noreturn?

我在C11写一个bootloader。 当引导加载程序需要将控制转移到固件时,它会在预定义的内存地址读取一个函数指针并调用它。 代码如下所示: typedef void (FirmwareBootFn)(void); typedef struct { uint32_t stackPointer; FirmwareBootFn* programCounter; } FirmwareBootControl; static FirmwareBootControl g_bootControl __attribute__ ((section (“.boot_control”))); void Firmware_boot( void ) { setStackPointer( g_bootControl.stackPointer ); g_bootControl.programCounter(); } 函数Firmware_boot()永远不会返回,所以将它声明为noreturn是有意义的: #include noreturn void Firmware_boot( void ); 但是我需要将FirmwareBootFn声明为noreturn ,以避免编译器抱怨Firmware_boot()可能会返回。 我尝试(可能) typedef中的noreturn每个排列没有任何结果。 另外我明白属性不能在typedef设置,因为它不是类型的一部分。 有没有办法标记我的Firmware_boot()作为noreturn避免警告(没有作弊警告抑制:-))?

clang c11 threads.h未找到

我试图在xcode中设置一个c11线程示例…但它似乎没有threads.h标头,虽然它没有抱怨这里描述的宏: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf __STDC_NO_THREADS__整数常量1,用于指示实现不支持标头。

为什么我可以在gcc -std = c11中使用gets()?

gets()函数已从C语言中删除。 标准中不存在此类function。 然而,我编译以下代码: #include int main (void) { (void) gets (NULL); } 运用 gcc -std=c11 -pedantic-errors -Wall -Wextra 它编译时不会出现任何错误或警告。 同样的, #include int gets; int main (void) {} 不会编译(错误:’获得’重新声明为不同类型的符号)。 在标准4.一致性§6中,我们可以阅读: 符合条件的实现可能具有扩展(包括附加库函数),前提是它们不会改变任何严格符合程序的行为 鉴于上述情况,我认为即使在迂腐模式下,gcc也不符合标准。 是否有一个原因? 这是故意还是错误? GCC版本4.9.1。 编辑: gcc –version gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.1

什么是C中的复合类型?

从§6.2.7.5 (第66页): 示例给定以下两个文件范围声明: int f(int (*)(), double (*)[3]); int f(int (*)(char *), double (*)[]); 由此产生的函数的复合类型是: int f(int (*)(char *), double (*)[3]); 在示例上方,他们解释了复合类型是一种类型,与两种不同类型兼容。 我会直观地将“复合类型”这个短语理解为“结构和联合”,这似乎是偏离目标的。 什么是C中的复合类型,它用于什么? 有人可以详细解释上面的例子吗?

是否存在支持负零的任何实现,或将其保留为陷阱表示?

在当前和年龄的大多数实现中,符号位的位模式为1且值位为0的有符号整数值往往表示该有符号整数类型的最低可能值。 但是,如6.2.6.2p2所述,这不是一项要求: 这些适用中的哪一个是实现定义的,就像符号位1和所有值位零(前两个),或符号位和所有值位1(对于补码)一样,是否为陷阱表示或正常值。 我的第一个问题很简单:是否有任何实现将此位模式用于负零或陷阱表示? 如果这个问题的答案是’不’,那么我后续问题的答案也必须是’不’。 继该问题之后, 6.2.6.2p3指出当为对象分配负零时,它可能(或可能不)转换为常规零: 未指定这些情况是否实际产生负零或正常零,以及当存储在对象中时负零是否变为正常零。 我的后续问题: 是否有任何实现使用陷阱表示而不是该位模式的负零? 是否有任何使用负零的实现存储为不同的值? 是否有任何使用负零的实现存储为常规零? 编辑澄清:我不是要求在一个系统中理论上可行的是什么,该系统使用补码,二进制补码或有符号整数的符号和幅度表示。 我可以在本问题前面引用的章节中找到(并且已经找到)这些信息。 我问的是实际做了什么 。

C1x:何时降落,会发生什么?

许多编译器仍然不支持C99,现在大部分时间都集中在C ++和即将推出的标准C ++ 1x上。 我很好奇C会在下一个标准中获得什么,何时会获得它,以及它将如何保持C的竞争力。 众所周知,C和C ++是相互依赖的改进,C是否会以C ++ 1x标准为基础? 在C的未来我能期待什么?

我是否需要GCC和C11的-dantic旗帜?

我目前正在使用GCC-5.3在我的机器上运行Linux Mint ,因为C11是默认包含的。 我开始为自己学习C只是为了好玩,当时GCC版本是4.8如果我没记错的话。 如果在下面的程序中使用带有-pedantic标志的GCC-4.8 ,任何方式: #include #include int main(void){ char *arr = “123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890”; size_t length = strlen(arr); printf(“Length of Arr = %zu\n”,length); } 在编译时,会收到以下警告: program.c: In function ‘main’: program.c:5:5: warning: string length ‘510’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings] char *arr = “123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890”; ^ program.c:7:5: warning: […]