Tag: language lawyer

是“int * ptr = *((&a)+ 1);”其中“a”是由标准明确定义的int ?

基于这个问题( c中的奇怪输出问题 )有一个答案( 由@Lundin提供 )关于这一行: int *ptr = (int*)(&a+1); 在哪里他说: the cast (int*) was hiding this bug 。 所以我带来了以下内容: #include int main( void ){ int a[5] = {1,2,3,4,5}; int *ptr = *( ( &a ) + 1 ); printf(“%d”, *(ptr-1) ); } 我想知道这是否: int *ptr = *( ( &a ) + 1 ); 标准明确定义了吗? 编辑 […]

总和+++我在C中的未定义行为?

我在不同的机器和不同的编译器上测试了这个,但是我给出了相同的输出: int sum = 10, i = 5; printf(“%d”, sum+++i); 这是C中明确定义或未定义的行为吗?

C有像C ++这样的一个定义规则吗?

最近,我发现有些情况绝对会违反C ++的ODR,但会在C编译器中编译好。 例如,这个奇怪的场景(和我一起): 来源1 int var_global=-3; 来源2 #include #include unsigned int var_global; int main() { printf(“%d \n”,var_global); getch(); return 0; } 我的打印结果是-3 (即使在Source 2中 var_global是unsigned )并且没有关于var_global 重新定义的var_global 。 我知道C与C ++有不同的规则,但我认为它不是那么不同。 我有谷歌并阅读了很多结果,但没有像 C ++ 这样的官方结果。 所以问题是: C有像C ++这样的一个定义规则吗? 和: 什么叫官方? 我需要它与C ++规则进行比较,这样我才能更深入地理解这两种语言。 p / s:我使用Visual Studio 2010编译上面的代码。

是否定义了在无法到达的路径上具有未定义行为的程序的行为?

考虑 void swap(int* a, int* b) { if (a != b){ *a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b; } } int main() { int a = 0; int b = 1; swap(&a, &b); // after this b is 0 and a is 1 return a > b […]

使用C ++方式对结构和数组进行别名

这是我的另一个问题的 C ++后续 在ISO C之前的旧时代,以下代码会让人感到惊讶: struct Point { double x; double y; double z; }; double dist(struct Point *p1, struct Point *p2) { double d2 = 0; double *coord1 = &p1->x; double *coord2 = &p2->x; int i; for (i=0; i<3; i++) { double d = coord2[i] – coord1[i]; // THE problem d2 += d * […]

‘goto * foo’其中foo不是指针。 这是什么?

我正在玩标签作为值 ,最后得到这个代码。 int foo = 0; goto *foo; 我的C / C ++经验告诉我*foo意味着dereference foo并且这不会编译因为foo不是指针。 但它确实编译。 这实际上是做什么的? gcc (Ubuntu 4.9.2-0ubuntu1~12.04) 4.9.2 ,如果重要的话。

int a = 1,b = a ++; 调用未定义的行为?

int a=1, b=a++; 调用未定义的行为? 在a的初始化和b的初始化程序中a访问和修改之间没有序列点介入,但据我所知,初始化不是对象的“修改”; 指定初始值设定项以提供对象的“初始值”。 根据6.7.8初始化,第8段: 初始值设定项指定存储在对象中的初始值。 在对对象进行任何访问之前对“初始”进行排序似乎是合理的。 此问题是否已经考虑过,是否有可接受的解释?

字符串终止符’\ 0’如何与整数常量0具有相同的值?

我有以下代码 – #include #define LENGTH 5 int main(){ char* ch[LENGTH] = {“Zero”, “One”, “Two”, “Three”, “Four”}; char* pc; char** ppc; for(int i=0; i<LENGTH; i++){ ppc = ch+i; pc = *ppc; while(*pc != 0){ printf("%c ", *pc); pc = pc +1; } printf("\n"); } return 0; } 它是使用字符串的多个间接的示例。 输出是 Z ero O ne T wo T […]

使用malloced内存未定义写入前读取?

根据这个reddit注释线程 ,如果在写入内存之前尝试读取内存,则它是未定义的。 我指的是正常的堆内存,它已成功地进行了malloc编辑。 …请注意,这不是严格有效的C:允许编译器/运行时系统使用所谓的陷阱表示来初始化未初始化的内存,这会导致访问时出现未定义的行为。 我觉得很难相信。 有标准报价吗? 当然,据我所知,无法保证内存已被清零。 这个未初始化的存储器中的值基本上是伪随机的或任意的。 但我真的不相信标准会将此称为未定义的行为 (从某种意义上说它可能是段错误,或者删除所有文件,或者其他什么)。 其余的reddit线程没有对此问题进行更多说明。

如果getc()通过SIGINT退出,则可能在getc()之后的未定义行为会改变程序行为

在“未定义行为”的现代解释下,编译器有权假设不会发生导致未定义行为“不可避免”的事件链,并且可以消除仅在代码将要执行的情况下适用的代码。未定义的行为; 这可能会导致未定义行为的影响及时向后工作,并使原本可以观察到的行为无效。 另一方面,如果除非程序终止,否则未定义行为将是不可避免的,但程序在调用未定义行为之前可以并且确实终止,程序的行为将保持完全定义。 在做出此决定时,需要考虑编译器的原因是什么? 举几个例子: 在许多平台上,对“getc”之类的函数的调用通常会返回(至少最终),但在某些情况下,编译器无法控制。 如果有一个程序,如: int main(int argc, char *argv[]) { if (argc != 3) { printf(“Foo\n”); return 0; } else { int ch; printf(“You’d better type control-C!\n”); int ch = getc(); if (ch < 65) return (ch-33) / (argc-3); else return INT_MAX + ch; } } 如果在argc等于3的情况下调用程序,则会定义行为,但是SIGINT阻止了getc()调用的返回? 当然,如果getc()可以返回哪个值会导致定义的行为,那么在编译器可以确定不会接收到这样的输入之前,不会发生未定义的行为。 如果没有值getc()可以返回,这将避免未定义的行为,但是,如果阻止getc()返回任何值,整个程序是否仍然定义? getc()的返回值与调用未定义行为的操作之间是否存在因果关系会影响事物(在上面的示例中,编译器无法知道任何特定forms的未定义行为会在不知道输入的字符的情况下发生,但任何可能的输入都会触发某种forms)。 同样,如果在平台上存在地址,如果读取,则指定导致程序立即终止,编译器指定易失性读取将触发硬件读取请求,并且该平台上的某些外部库指定它将返回指针对于这样一个地址,这些因素是否意味着在这个单独的例子中bar的行为: int […]