相关疑难解决方法(0)

是GCC的选择-O2打破这个小程序还是我有未定义的行为

我在一个非常大的应用程序中发现了这个问题,从中做了一个SSCCE.我不知道代码是否有未定义的行为或-O2打破它.

gcc a.c -o a.exe -O2 -Wall -Wextra -Werror它编译时打印5.

但是在编译时没有(例如)或取消注释2条注释行之一(防止内联)时打印25.-O2-O1

#include <stdio.h>
#include <stdlib.h>
// __attribute__((noinline)) 
int f(int* todos, int input) {
    int* cur = todos-1; // fixes the ++ at the beginning of the loop
    int result = input;
    while(1) {
        cur++;
        int ch = *cur;
        // printf("(%i)\n", ch);
        switch(ch) {
            case 0:;
                goto end;
            case 1:;
                result = result*result;
            break;
        }
    }
    end:
    return result;
}
int main() …
Run Code Online (Sandbox Code Playgroud)

c gcc inline-functions compiler-optimization

14
推荐指数
1
解决办法
610
查看次数

为什么printf()在Windows上打印这个神秘的额外文本?

我最近写了一个简单的程序来反转一个字符串,我的程序只是接受来自用户的输入字符串然后反转它.这一切都是用2个指针完成的.关于程序中的指针安全性,我编写了一个复制给定字符串的函数,该函数为新的(相同长度)字符串分配内存,然后逐个复制字符.

我的问题是当我运行这个程序时,虽然它做了我需要的东西,它打印出一些神秘的额外输出.在接受用户的输入之前,它每次都这样做.这是我运行程序时发生的情况.

C:\Users\0xEDD1E\Desktop\revstr>revstr.exe
[C]
[.]
[revstr.exe]
hello
[hello]
olleh
Run Code Online (Sandbox Code Playgroud)

这里最后三行是输入和输出,没关系,问题出在前3行

[C]
[.]
[revstr]
Run Code Online (Sandbox Code Playgroud)

那些是什么?无论如何,这是我的计划

#include <stdio.h>
#include <stdlib.h>

#define swap(a, b) (((a) ^ (b)) && ((a) ^= (b), (b) ^= (a), (a) ^= (b)))

unsigned long strlen_(char *);
char *strdup(char *s);
char *reverseString(char *, int);

int main(void)
{
    //fflush(stdout);
    char *str = (char *) malloc(1024 * sizeof (char));
    scanf("%[^\n]s", str);
    int slen = strlen_(str);
    printf("%s\n", reverseString(str, slen));
    return 0;
}

unsigned long strlen_(char *s)
{
    char *p = s;
    while …
Run Code Online (Sandbox Code Playgroud)

c printf pointers

10
推荐指数
1
解决办法
790
查看次数

指针比较">"与数组对象的第一个元素之前的一个

根据该主题,允许将指针与数组对象的最后一个元素之一进行比较.

根据@jalf注释,禁止在数组对象的第一个元素之前将指针与一个进行比较.

例1

int array[10];
int *ptr;
for(ptr=&array[9]; ptr>(array-1); ptr--) {...}
Run Code Online (Sandbox Code Playgroud)

例题

int array[10];
int *ptr;
for(ptr=&array[9]; ptr>=(array); ptr--) {...}
Run Code Online (Sandbox Code Playgroud)

1)是否禁止example1example2

2)C标准是否有证据表明禁止在数组对象的第一个元素之前比较指针?

c c++ comparison pointers

9
推荐指数
1
解决办法
993
查看次数

对已经寻址数组基址的指针应用后递减是否会调用未定义的行为?

在寻找关于以下内容的相关或重复问题后无济于事(我只能用边际正义来描述用C标记的指针算术和后减法问题的绝对数量,但足以说"船载"做了一个坟墓对结果集的不公平)我把它扔在戒指中,希望澄清或转介给我的副本.

如果将后递减运算符应用于如下所示的指针(数组序列的简单反向迭代),以下代码是否会调用未定义的行为?

#include <stdio.h>
#include <string.h>

int main()
{
    char s[] = "some string";
    const char *t = s + strlen(s);

    while(t-->s)
        fputc(*t, stdout);
    fputc('\n', stdout);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

最近向我提出6.5.6.p8 Additive运算符,结合6.5.2.p4,Postfix递增和递减运算符,指定甚至在它已经包含调用未定义行为的基地址时执行后递减,无论是否评估(不是表达式结果)的结果值.我只是想知道是否确实如此.tstt--

标准的引用部分是:

6.5.6加法运算符

  1. 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.

和...几乎紧密耦合的关系......

6.5.2.4后缀增量和减量运算符约束

  1. 后缀增量或减量运算符的操作数应具有原子,限定或非限定的实数或指针类型,并且应为可修改的左值.

语义

  1. postfix ++运算符的结果是操作数的值.作为副作用,操作数对象的值递增(即,将相应类型的值1添加到其中).有关约束,类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论.在更新操作数的存储值的副作用之前,对结果的值计算进行排序.对于不确定顺序的函数调用,后缀++的操作是单个评估.具有原子类型的对象上的Postfix ++是具有memory_order_seq_cst内存顺序语义的读 - 修改 - 写操作.98)

  2. 所述后缀-操作者是类似于后缀++操作,不同的是操作数的值被递减(即,相应的类型的值1被从中减去).

前向参考:加法运算符(6.5.6),复合赋值(6.5.16.2).

在发布的示例中使用post-decrement运算符的原因是为了避免针对数组的基址评估最终无效的地址值.例如,上面的代码是以下的重构:

#include <stdio.h>
#include <string.h>

int main() 
{
    char s[] = "some string";

    size_t len = strlen(s);    
    char *t = …
Run Code Online (Sandbox Code Playgroud)

c arrays pointers

7
推荐指数
1
解决办法
251
查看次数