相关疑难解决方法(0)

我怎样才能让gcc警告我"int i = i;"

一个简单的程序:

int main()
{
    long i = i;

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

编译为C不会出现错误,也不会出现警告.

$ gcc -Wall -Wextra -pedantic 1.c
Run Code Online (Sandbox Code Playgroud)

编译为C++会发出警告:

$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
  long i = i;
Run Code Online (Sandbox Code Playgroud)

在两种情况下,变量i似乎都是0,尽管在c ++中它可能是未初始化的.我实际上在我的一个功能中犯了这样的错字,很难找到它.我该怎么做才能避免这种情况?我希望至少有一个警告.此外,Clang在任何一种情况下都不会给出任何警告(c或c ++).是否有标准的特定部分说明了这种行为?

编辑:尝试了类似的东西:

$ cat 1.c
int main(void)
{
    int k = k + 0;
    int i = i + 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

警告(在C中)仅针对"i"生成.

$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: …
Run Code Online (Sandbox Code Playgroud)

c c++ gcc std compiler-warnings

27
推荐指数
1
解决办法
853
查看次数

静态constexpr变量的自我初始化是否格式良好?

在全局命名空间中给出以下声明:

constexpr int x = x;
Run Code Online (Sandbox Code Playgroud)

这个结构良好吗?

草案C++ 14标准部分3.6.2 [basic.start.init]说:

具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应在任何其他初始化发生之前进行零初始化(8.5).[...]

似乎使得示例定义良好的是x在常量初始化期间使用其自己的值初始化,这将0归因于零初始化.

这是真的吗?当gcc生成诊断时,clang 接受此代码:

error: the value of 'x' is not usable in a constant expression
constexpr int x = x;
                  ^
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++14 c++17

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

未初始化变量的后果:int vs unsigned char

我在cppreference.com上看到了以下示例

int x;     // OK: the value of x is indeterminate
int y = x; // undefined behavior
Run Code Online (Sandbox Code Playgroud)

这里int y = x;未定义的行为,因为它x是未初始化的.

但,

unsigned char c;     // OK: the value of c is indeterminate
unsigned char d = c; // OK: the value of d is indeterminate
Run Code Online (Sandbox Code Playgroud)

这里unsigned char d = c;不确定的行为,但unsigned char c;也是一个未初始化的变量.

那么,为什么unsigned char d不确定的价值呢?

c++ initialization undefined-behavior language-lawyer

25
推荐指数
2
解决办法
1643
查看次数

为什么现代C++编译器不能优化这样的简单循环?(Clang,MSVC)

当我使用Clang(-O3)或MSVC(/O2)编译并运行此代码时...

#include <stdio.h>
#include <time.h>

static int const N = 0x8000;

int main()
{
    clock_t const start = clock();
    for (int i = 0; i < N; ++i)
    {
        int a[N];    // Never used outside of this block, but not optimized away
        for (int j = 0; j < N; ++j)
        {
            ++a[j];  // This is undefined behavior (due to possible
                     // signed integer overflow), but Clang doesn't see it
        }
    }
    clock_t const finish = …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang compiler-optimization visual-c++

24
推荐指数
2
解决办法
1854
查看次数

int x; int y; int*ptr; 是不是初始化,对吧?

我正在阅读JP Mueller和J. Cogswell撰写的"C++ All-in-One for Dummies"并偶然发现:

#include <iostream>
using namespace std;
int main()
{
    int ExpensiveComputer;
    int CheapComputer;
    int *ptrToComp;
...
Run Code Online (Sandbox Code Playgroud)

这段代码首先初始化所有涉及的东西 - 两个整数和一个指向整数的指针.

只是为了确认,这是一个错误,应该读作'......通过声明',对吧?对我来说,这样的基本错误仍然会出现在书中,这一点很奇怪.

c++ terminology initialization declaration language-lawyer

24
推荐指数
2
解决办法
1823
查看次数

在自己的初始化程序中使用变量

C++20 标准草案的[basic.scope.pdecl]/1在注释中包含以下(非规范性)示例(合并拉取请求 3580之前的部分引用,请参阅此问题的答案):

unsigned char x = x;
Run Code Online (Sandbox Code Playgroud)

[...] x 用它自己的(不确定的)值初始化。

这实际上在 C++20 中有明确定义的行为吗?


通常T x = x;,由于x的值在初始化完成之前是不确定的,因此表单的自初始化具有未定义的行为。评估不确定的值通常会导致未定义的行为([basic.indent]/2),但在[basic.indent]/2.3中有一个特定的例外,它允许直接unsigned charunsigned char具有不确定值的左值初始化变量(导致使用不确定值初始化)。

这本身并不会因此导致不确定的行为,但会为其他类型T不属于无符号窄字符类型或std::byteint x = x;。这些注意事项也适用于 C++17 及之前的版本,另请参阅底部的链接问题。

然而,即使对于unsigned char x = x;,当前草案的[basic.lifetime]/7说:

类似地,在对象的生命周期开始之前 [...] 使用不依赖于其值的泛左值的属性是明确定义的。在以下情况下,程序具有未定义的行为:

  • 泛左值用于访问对象,或

  • [...]

这似乎意味着x示例中的that值只能在其生命周期内使用。

[basic.lifetime]/1说:

[...]

类型 T 的对象的生命周期在以下情况下开始:

  • [...] 和
  • 它的初始化(如果有)完成(包括空初始化)([dcl.init]),

[...]

因此x的生命周期仅在初始化完成后才开始。但是在引用的例子中 …

c++ initialization lifetime language-lawyer c++20

23
推荐指数
1
解决办法
637
查看次数

我们是否可以将未明确引用的内容应用于C++标准的规范性引用?

在C++ 11标准中(最接近的草案是N3337)部分1.2 规范性参考文献说:

以下参考文件对于本文件的应用是必不可少的.凡是注日期的引用文件,仅引用的版本适用.凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于本标准.

但是没有关于如何应用参考文献的指南.简单的情况是当C++ 11明确引用回引用时,例如在3.9.1 基本类型部分中它说:

[...]有符号和无符号整数类型应满足C标准第5.2.4.2.1节中给出的约束.

但是,没有明确参考的其他情况呢?例如,C++ 11使用单词indeterminate值,但它没有定义术语.规范性参考文献包括:

- ISO/IEC 9899:1999,编程语言 - C.

[...]

- ISO/IEC 9899:1999/Cor.3:2007(E),编程语言 - C,技术勘误3

和C99(草案c99标准)确实对部分中的不确定值有一个定义,3.17.2其中说:

要么是未指定的值,要么是陷阱表示

如果通过引用C99定义C++ 11来定义不确定值是否正确,就像这个答案似乎对于bit的定义一样?如果是的话,什么陷阱表示这是覆盖在部分6.2.6.15代表处类型的C99?

慷慨的解读是,只要C++ 11中没有任何内容与规范性引用冲突就适用,这是正确的解释吗?一些答案是什么是C++中的不确定行为?它与未定义的行为有什么不同?似乎意味着慷慨的阅读,虽然在一些答案中语言有点宽松,所以很难说出某些要点究竟是什么.

c++ standards iso language-lawyer c++11

22
推荐指数
1
解决办法
620
查看次数

C++零初始化

根据http://en.cppreference.com/w/cpp/language/zero_initialization,我无法理解何时以及为什么我的班级中的某个成员是零初始化的.

考虑以下测试程序:

#include <iostream>
#include <stdio.h>

class MyTest {
private:
    const static unsigned int dimension = 8;
    void (* myFunctions [dimension])();

public: 
    MyTest() {}

    void print() { 
        for(unsigned int i=0; i < MyTest::dimension; i++) {
            printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);
        }   
    }
};


int main() {
    //We declare and initialize an object on the stack 
    MyTest testObj = {};
    testObj.print();

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

我声明一个类有一个包含签名"void functionname()"的8个函数指针的数组.当我宣布和初始化类的对象main作为MyTest testObj = {};或者MyTest testObj;,我希望它是零初始化,即所有指针都是空指针.

但是,在带有g++ -m32 …

c++ c++14 zero-initialization

22
推荐指数
1
解决办法
4836
查看次数

从未初始化的变量memcpy是未定义的行为吗?

是使用未初始化的变量作为srcmemcpy用C未定义行为?

void foo(int *to)
{
  int from;
  memcpy(to, &from, sizeof(from));
}
Run Code Online (Sandbox Code Playgroud)

c memcpy undefined-behavior language-lawyer

21
推荐指数
2
解决办法
1835
查看次数

这种自我指派是否做了明智的事情?

我刚刚在一个函数中找到了这行代码,这让我很困惑.这在任何情况下都有意义,还是未定义的行为?

char * acFilename = acFilename;
Run Code Online (Sandbox Code Playgroud)

编辑:编译器抱怨警告C4700,我正在使用未初始化的变量.

c c++

20
推荐指数
3
解决办法
4070
查看次数