标签: sequence-points

我应该使用哪些编译标志来避免运行时错误

刚刚在这里学到,-Wsequence-point当代码可以调用UB时,comiplation标志会弹出警告.我在类似的声明上尝试过

int x = 1;
int y = x+ ++x;
Run Code Online (Sandbox Code Playgroud)

它工作得非常好.到目前为止,我已编译gccg++仅使用-ansi -pedantic -Wall.你有没有其他有用的标志来使代码更安全和健壮?

c c++ compiler-flags compiler-warnings sequence-points

8
推荐指数
1
解决办法
353
查看次数

结构成员初始化之间是否存在序列点?

结构成员初始化表达式之间是否有一个序列点?

例如,是否明确定义下面的代码将始终打印"a,b"?

#include <stdio.h>

typedef struct {
    char *bytes;
    int position;
    int length;
} Stream;

typedef struct {
    char a;
    char b;
} Pair;

char streamgetc(Stream *stream) {
    return (stream->position < stream->length) ? stream->bytes[stream->position++] : 0;
}

int main(void) {
    Stream stream = {.bytes = "abc", .position = 0, .length = 3};
    Pair pair = {.a = streamgetc(&stream), .b = streamgetc(&stream)};
    printf("%c, %c\n", pair.a, pair.b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c sequence-points language-lawyer

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

为什么gcc不会在代码里面的未定义行为中发出警告?

我刚读了这篇关于未定义行为和序列点的SO C++ FAQ,并进行了一些实验.在下面的代码中gcc-4.5.2,只在代码注释中提到的行中给出了警告,尽管之前的一行也显示了未定义的行为,不是吗?您不能说首先执行哪个加法操作数(因为+没有序列点).为什么gcc也没有在这一行给我一个警告?

int i=0;
int j=0;

int foo(void) {
    i=1;
    return i;
}

int main(void) {
    i = i + foo(); 
    j = j + (j=1); //Here is a rightly warning
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮忙.

c c++ gcc compiler-warnings sequence-points

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

序列点与运算符优先级

可能重复:未
测序的值计算(也称为序列点)
未定义的行为和序列点
运算符优先级与评估顺序

我仍然试图围绕以下表达式如何导致未定义的行为:

a = a++;
Run Code Online (Sandbox Code Playgroud)

在搜索SO时,我发现了以下问题:

序列点和运算符优先级之间的差异?0_o

我仔细阅读了所有答案,但我仍然对细节有困难.其中一个答案描述了我的上述代码示例的行为在a修改方面是不明确的.例如,它可以归结为以下任何一种:

a=(a+1);a++;
a++;a=a;
Run Code Online (Sandbox Code Playgroud)

究竟什么使a修改变得模棱两可?这是否与不同平台上的CPU指令有关,以及优化器如何利用未定义的行为?换句话说,由于生成的汇编程序,它似乎未定义?

我没有看到编译器使用的原因a=(a+1);a++;,它只是看起来古怪而且没有多大意义.什么会让编译器使它以这种方式运行?

编辑:

为了清楚起见,我确实理解正在发生的事情,我只是不明白当有关于运算符优先级的规则(它基本上定义了表达式的求值顺序)时它是如何被定义的.在这种情况下,赋值最后发生,因此a++需要首先进行评估,以确定要分配的值a.所以我期望的是a,在修复后增量期间首先修改,但随后产生一个值以分配回a(第二次修改).但运算符优先级的规则似乎使我的行为非常清楚,我没有找到任何"摆动空间",因为它有未定义的行为.

c++ sequence-points

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

函数调用的序列点?

这是另一个序列点问题,但是一个相当简单的问题:

#include <stdio.h>
void f(int p, int) {
  printf("p: %d\n", p);
}

int g(int* p) {
  *p = 42;
  return 0;
}

int main() {
  int p = 0;
  f(p, g(&p));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是未定义的行为吗?或者调用g(&p)充当序列点?

c c++ undefined-behavior sequence-points

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

这个C语句的顺序是否定义良好?

标题有点模糊,因为我真的不知道如何定义这个问题.

它与以下代码有关:

for (match         = root,
     m_matchBase   = match->requestedBase,
     m_matchLength = match->length;

     match != NULL;

     match         = match->next,
     m_matchBase   = match->requestedBase,
     m_matchLength = match->length)
{
    if (m_matchBase <= m_base && m_matchBase + m_matchLength > m_base)
        break;
    // other stuff...
}
Run Code Online (Sandbox Code Playgroud)

for循环中的语句是否保证按顺序运行?

例如,m_matchBase = match->requestedBase保证运行之后match = match->next

c sequence-points

7
推荐指数
2
解决办法
222
查看次数

如何在c中检查该行为是否未定义?

我知道以下是未定义的,因为我试图在同一个表达式中读取和写入变量的值,即

int a=5;
a=a++;
Run Code Online (Sandbox Code Playgroud)

但如果是这样,那么为什么以下代码片段未定义

int a=5;
a=a+1;
Run Code Online (Sandbox Code Playgroud)

在这里我也试图修改它的值a并同时写入它.

还解释了为什么标准没有解决这个问题或者删除这个未定义的行为,尽管事实上他们知道它是未定义的?

c undefined-behavior sequence-points

7
推荐指数
3
解决办法
744
查看次数

在c ++中,作业的一侧是在另一侧之前排序吗?

我知道这是未定义的行为:

int i = 0;
int a[4];
a[i] = i++;  //<--- UB here
Run Code Online (Sandbox Code Playgroud)

因为i左手侧和右手侧的评估顺序是不确定的(这;是唯一的序列点).

把这个推理更进一步,在我看来,这将是 未定义 未指明的行为:

int i = 0;

int foo(){
    return i++;
}

int main(){
    int a[4];
    a[i] = foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

尽管在=我理解的情况下,在右侧有一些序列点仍然存在未定义未指定是否f()a[i]首先评估.

我的假设是否正确?当我在作业的左侧使用全局或静态变量时,我是否必须小心谨慎,右手在任何情况下都不会修改它?

c++ sequence-points

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

C++ 11中的安全短路评估

Pre-C++ 11我们知道运营商需要短路和评估顺序,&&因为:

1.9.18

在评估以下表达式时

a && b
a || b
a ? b : c
a , b
Run Code Online (Sandbox Code Playgroud)

使用这些表达式中运算符的内置含义,在评估第一个表达式(12)之后有一个序列点.

但是C++ 11中不再存在序列点,因此标准部分在哪里说:

if (ptr && ptr->do_something())
{
}
Run Code Online (Sandbox Code Playgroud)

是安全的?

c++ short-circuiting sequence-points c++11

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

在声明VLA的同一序列点中启动VLA的大小部分是否有效?

这篇文章中,OP包含有很多错误的代码,但是1行让我特别好奇,因为我无法查看任何东西,不允许它.这是具体的一行:

int n = 100000, arr[n];
Run Code Online (Sandbox Code Playgroud)

是否确保了声明和初始化的顺序?

所以在这里我会假设它甚至可能发生narr获得声明时没有被初始化,看起来很不好.

但是我无法在iso/iec 9899草案中找到任何关于此的陈述,既没有说明未定义也没有定义它.

这是因为我假设未定义的行为?或者是吗?

无论哪种方式,该结果适用的规则是什么?5

编辑:

这对C99也有效吗?

c sequence-points variable-length-array

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