Tag: 语言律师

C和C ++操作数解析顺序

很多时候,我看到(有时写)代码与此示例类似: int a=0, b=2; if( a && (b=func())!=0 ) { //… 问题是:标准是否保证这些陈述? b将不被触及(并保持值2 ) 不会调用func() 反之亦然,如果我们写if( func()!=0 && a ) – 是否会调用标准保证func() ? 我对定义这个合法的特定标准段感兴趣。 UPD:我的拼写错误,从int a=1更改为int a=0

在C标准库中转发声明实体?

转发C标准库提供的结构和函数是否合法? 我的背景是C ++,答案是否定的。 这样做的主要原因是C ++标准库强制要求的结构或类可以是幕后模板,并且可能具有“秘密”模板参数,因此无法使用天真的非模板声明正确声明。 即使用户确实弄清楚如何在特定实现的特定版本中转发声明特定实体,实现也没有义务在未来版本中不破坏该声明。 我手边没有任何C标准的副本,但显然C中没有模板。 那么在C标准库中转发声明实体是否合法? C ++标准库中的实体可能无法向前声明的另一个原因是实现提供的头文件不需要遵循常规规则。 例如,在最近的一个问题中,我询问实现提供的C ++头是否需要是一个实际文件而答案是否定的。 我不知道是否有任何适用于C. C和C ++都使用C标准库,但对于这个问题,我只问C。

释放指针的算法

在阅读这个SO问题的答案时,我了解到越界指针算法是未定义的。 的确,根据C99 6.5.6第8段 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义。 释放该对象会使该保证无效吗? 7.20.3.2“自由function”似乎没有提到它,只是提到“空间被解除分配”。 由于6.5.6特别提到溢出,它似乎是一个整数溢出问题,free不会影响。 指向对象的指针的算术是“引用它”的行为吗? 换句话说,是: char *foo = malloc(10); free(foo); foo++; 未定义? 或者“溢出”的用法是不同的?

所有C和C ++版本中的所有有效类型都是有符号,无符号,长和短吗?

在N3797 7.1.1 / 3中,有以下注释: Note: Since signed, unsigned, long, and short by default imply int, a type-name appearing after one of those specifiers is treated as the name being (re)declared. 但这只是一个说明。 是否在标准中的某个地方做出了相同的规范性陈述? 在每种情况下,是否使用符合标准的C和C ++来使用signed , unsigned , long和short而不使用int ? 或者,将它放在代码中,是否遵循以下标准?如果是这样,它在哪里这样说? signed a; unsigned b; short c; long d; signed f(signed p, unsigned q, short r, […]

长度为0的可变长度数组?

在C中,通常不允许数组的大小为0(除非我使用一个或其他编译器端扩展)。 OTOH,有长度可能为0的VLA。 他们被允许吗? 我在谈论以下代码: void send_stuff() { char data[4 * !!flag1 + 2 * !!flag2]; uint8_t cursor = 0; if (flag1) { // fill 4 bytes of data into &data[cursor] cursor += 4; } if (flag2) { // fill 2 bytes of data into &data[cursor] cursor += 2; } } 结果是一个长度为0,2,4或6的data数组,具体取决于标志的组合。 现在的问题是:对于数组结果长度为0的情况,这个有效代码是什么?

被有效的类型规则困惑

我似乎再次错过了关于有效类型的几个难题……代码中的注释基本上是我的问题,但这是我能够用适当的上下文来思考这个问题的唯一方法。 #include #include typedef struct foo { int n; } Foo; int main(void) { // No effective type yet because there has been no write to the memory. Foo *f = malloc(sizeof(Foo)); // Effective type of `f` is now `Foo *`, except I’m writing to // `f->n`, so shouldn’t it be `int *`? Not sure […]

DBL_MAX的类型

我在某处看到了这段代码 printf(“DBL_MAX : %g\n”, (double) DBL_MAX); 演员是必要的吗? 我在标准中找不到任何指定DBL_MAX必须实际拥有(或提升)类型为double 。

包含不可表示字符的三字符的字符文字的含义

在使用ASCII作为字符集的C编译器中,字符文字’??<'将等于'{‘ ,即0x7B。 在字符集没有{字符?的编译器上,该文字的值是多少? 在字符串文字之外,编译器可以推断??<应该具有与开括号字符相同的含义 ,即使编译器字符集没有开括号字符。 实际上,三字符的整个目的是允许使用可表示字符序列来代替不可表示的字符。 该规范要求三字符甚至在字符串文字中处理,然而,这让我感到困惑。 如果编译器的字符集包含{字符,编译器可以允许'{‘表示为’??<' ,但字符集包括{我看不出程序员不会简单地使用它。 如果字符集不包含{ ,但是,这似乎是首先使用三元组的唯一原因,编译器应该用什么可表示的字符替换??< with?

在C中,是否保证数组起始地址小于其他元素的地址?

换句话说 index = &array[x] – &array[0]; 总是保证(根据C标准)&array [0] <=&array [x],还是依赖于编译器? 与此主题相关的C标准章节是什么?

isspace()是否接受getchar()值?

如果输入可表示为unsigned char或等于EOF则isspace()有效。 getchar()从stdin中读取下一个字符。 当getchar()!=EOF ; 所有getchar()返回的值都可以表示为unsigned char吗? uintmax_t count_space = 0; for (int c; (c = getchar()) != EOF; ) if (isspace(c)) ++count_space; 愿这段代码导致未定义的行为吗?