Tag: 标准

C标准中char数组结构成员的对齐方式

让我们假设我想读/写一个tar文件头。 考虑到标准C(C89,C99或C11),char数组在结构上是否有任何特殊处理,关于填充? 编译器可以为这样的结构添加填充: struct header { char name[100]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char chksum[8]; char typeflag; char linkname[100]; char tail[255]; }; 我已经看到它也用在网络上的代码中。 只是自由,将这个结构写入一个块中的文件,假设不会有任何填充。 当然也假设CHAR_BITS == 8 。 我认为这样的C代码是如此常见,标准会处理这种情况,但我无法找到它,也许我不会是一个好律师。 编辑 接受的答案将根据C标准之一给出严格或最严格的可移植实现,这使我可以使用标准库字符串函数处理这些字段。 考虑CHAR_BITS和所有。 我认为需要为此读取512 uint8_t的数组,之后可能会将它们逐个转换为chars。 有更简单的方法吗

c标准和位移

这个问题首先受到此代码的(意外)结果的启发: uint16_t t16 = 0; uint8_t t8 = 0x80; uint8_t t8_res; t16 = (t8 << 1); t8_res = (t8 << 1); printf("t16: %x\n", t16); // Expect 0, get 0x100 printf(" t8: %x\n", t8_res); // Expect 0, get 0 但事实certificate这是有道理的: 6.5.7按位移位运算符 约束 2每个操作数应具有整数类型 因此最初混淆的线相当于: t16 = (uint16_t) (((int) t8) << 1); 有点不直观的恕我直言,但至少定义明确。 好的,很棒,但接下来我们做了: { uint64_t t64 […]

块范围链接C标准

以下标识符没有链接:声明为对象或函数以外的任何标识符; 声明为函数参数的标识符; 在没有存储类说明符extern的情况下声明的对象的块作用域标识符 。 { static int a; //no linkage } 对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符的链接与链接相同在先前声明中指明。 如果没有先前声明可见,或者先前声明未指定链接 , 则标识符具有外部链接 。 { static int a; //no linkage extern int a; //a should get external linkage, no? } GCC错误:没有链接的以下声明的extern声明 有人可以解释我为什么会出现这个错误? 谢谢

为什么在C中的等式表达式中不允许使用结构?

结构体作为比较操作数的不可用性是C中比较明显的事情之一(对我而言)没有多大意义。 结构可以通过值传递并通过赋值复制,但是没有为它们指定== 。 下面是C11标准(草案)的相关部分,它们定义了相等运算符( ==和!= )和简单赋值运算符( = )的约束。 注意在等式运算符的约束中缺少结构和联合。 (除了缺乏处理_Atomic ,C99中的措辞是相同的)。 6.5.9平等运营商 约束 以下其中一项应持有: 两个操作数都有算术类型; 两个操作数都是指向兼容类型的限定或非限定版本的指针; 一个操作数是指向对象类型的指针,另一个是指向void的限定或非限定版本的指针; 要么 一个操作数是一个指针,另一个是空指针常量。 6.5.16.1简单分配 约束 以下其中一项应持有: 左操作数具有primefaces,限定或非限定算术类型,右边有算术类型; 左操作数具有与右侧类型兼容的结构或联合类型的primefaces,限定或非限定版本; 左操作数具有primefaces,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有全部右边指出的类型的限定词; 左操作数具有primefaces,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的指针void,左边指向的类型具有右边指向的所有类型的限定符; 左操作数是一个primefaces,限定或非限定指针,右边是一个空指针常量; 要么 左操作数的类型为atomic,qualified或nonqualified _Bool,右边是指针。 任何人都可以解释为什么存在这种差异(没有推测)?

严格别名和指向联合字段的指针

我有一个关于严格别名规则,工会和标准的问题。 假设我们有以下代码: #include union { int f1; short f2; } u = {0x1}; int * a = &u.f1; short * b = &u.f2; int main() { u.f1 = 1; *a += 1; u.f2 = 2; *b *= 2; printf( “%d %hd\n”, *a, *b); return 0; } 现在让我们来看看它是如何工作的: $ gcc-5.1.0-x86_64 tc -O3 -Wall && ./a.out 2 […]

结构成员与_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 […]

C条件总是会返回1还是0?

C条件语句总是返回[1或0],还是返回[0或’除零以外的值’]。 我问因为: 伪代码 – foo(地址,应该发送): 注册>> = 1 寄存器<< = 1 //清除第一个位置的位 register | = shouldSend //表示是否应该发送 如果某人在一个大于1的shouldSend值中传递了一个问题,那么就会出现问题(因为只有0是假而其他所有都是真的,技术上这是有效的)。 因为我直接用寄存器对theSend的真值进行OR运算,所以最好不要说0xFF! 我已经有了一个解决方案,所以问题更多的是出于好奇的缘故。 我想知道如果: foo(地址,应该发送): 注册>> = 1 寄存器<< = 1 //清除第一个位置的位 register | = (shouldSend> 0) //表示是否发送 解决了这个问题? 我认为现在传入的0xFF(或一般来说,大于1的东西)的问题被C条件掩盖。 但这只能保证IF C条件保证返回[0或1]。 ps – 我也意识到它可能依赖于编译器,但是ansi标准对此有何看法?

Visual C ++标准符合性

我想知道Microsoft的Visual C ++编译器是否以及在何种程度上符合当前的C(C90 / C99)和C ++(ISO / IEC 14882:2003)标准。 不幸的是,我只能找到关于这个主题的部分信息,我可能会看到所有错误的地方。 任何指向相关资源的指针都非常感谢。 提前致谢。 编辑:因为看起来这是一个最敏感的主题,我会满足于是否MSVC完全符合C90的是/否答案…我已经明白,这不是C99的情况(自然而然,我仍然不知道C ++ .. Edit2:感谢大家的回答。 我已经接受了Rushakov先生的回答,但对所有相关答案都提出了异议,这些答案都很有帮助。

atoi是一个标准function。 但是itoa不是。 为什么?

为什么这个区别? 我已经遇到了可怕的问题,假设itoa在stdlib.h ,最后将itoa的自定义版本与不同的原型相关联,从而产生一些疯狂的错误。 那么,为什么itoa不是标准function呢? 它出什么问题了? 为什么标准偏向其孪生兄弟atoi ?

哪个gcc和g ++版本支持c和c ++的哪个标准?

例如,哪个gcc版本支持c99? 是否有表格或图表来显示gcc和g ++的标准支持状态? gcc和g ++是如何演变的? 谢谢〜