Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这项自我分配是否明智?_C++_C - Fatal编程技术网

C++ 这项自我分配是否明智?

C++ 这项自我分配是否明智?,c++,c,C++,C,我刚刚在一个函数中发现了这行代码,这让我很困惑。这在任何情况下都有意义吗?或者这是未定义的行为 char * acFilename = acFilename; 编辑:编译器发出警告C4700,表示我正在使用未初始化的变量。否此代码没有任何意义。可能是打字错误,可能是有人想用的 char* acFilename = ::acFilename; 或 或者别的什么 它是最令人困惑和无用的,可能是一个bug,因为某人打算使用不同的变量。 < P>在块范围内,C++中,这是未定义的行为,作为变量在其初

我刚刚在一个函数中发现了这行代码,这让我很困惑。这在任何情况下都有意义吗?或者这是未定义的行为

char * acFilename = acFilename;

编辑:编译器发出警告C4700,表示我正在使用未初始化的变量。

否此代码没有任何意义。可能是打字错误,可能是有人想用的

char* acFilename = ::acFilename;

或者别的什么


它是最令人困惑和无用的,可能是一个bug,因为某人打算使用不同的变量。

< P>在块范围内,C++中,这是未定义的行为,作为变量在其初始化之前的右边(C++ 14 [DCL init)/ 12)。 在C11的块范围中,这可能是未定义的行为,也可能是未初始化的变量,具体取决于实现和函数其余部分的各种细节,以进行详细分析

在命名空间范围内,在C++中,OK定义良好,并生成空指针。这是因为在考虑初始值设定项之前,所有静态变量都是零初始化的。(C++14[basic.start.init]/2)


在C中的文件范围内,这是一个约束冲突;静态变量必须有一个常量表达式作为初始值设定项,并且变量的值不能是常量表达式。

我以前见过这个。由于gcc对未初始化的变量警告非常满意,所以这是一个使这些警告静音的技巧。不确定这是gcc有意的设计选择还是编译器的愚蠢,但我看到人们这样做是为了让gcc闭嘴(并在这个过程中打破未来可能正确的警告)

我只需要将其替换为初始化为NULL。这是一个坏习惯,在其他编译器上不起作用,空值的正确性不能低于不确定值和未定义行为

只是为了演示这是如何工作的(也是因为我想知道更新的gcc版本是否仍然这样做):


在程序中的某些位置,变量可能处于以下任一状态:

  • 已收到的输入已导致写入变量,并且还将导致代码在将来使用其值

  • 接收到的输入导致变量无法写入,但也会导致代码无法使用其值

  • 如果某些编译器看到存在会导致变量无法写入的输入,并且存在会导致变量读取的输入,则会发出嘎嘎声。即使导致变量被读取的唯一输入也会导致变量被写入,编译器也可能没有意识到这一点。虽然可以通过无条件地初始化变量来消除编译器的抱怨,但用一个永远无法实际使用的值初始化变量的机器代码将不起任何作用。因此,与需要生成无用机器代码的源代码结构相比,源代码结构更可取,它可以使编译器的抱怨保持沉默,但不会导致编译器生成无用机器代码。在某些编译器上,自初始化声明可能用于此目的

    如果一个类型有陷阱表示,那么除了编写一个编译器可能会变成无用的机器代码的初始化之外,可能没有其他实用的替代方法,但是如果一个类型没有陷阱表示,那么高质量的编译器就没有什么特别的理由来强迫程序员要求他们不想要也不需要的无用代码。然而,标准的作者并没有试图为各种类型有陷阱表示和没有陷阱表示的平台制定不同的规则,而是遵从实现者的判断,即对于特定的目标平台和应用程序领域,哪些行为是合理的

    如果在某些平台上,编译器不能允许程序员忽略已复制但未使用的变量的初始化,而不必生成可能的冗余初始化本身,那么要求程序员在实际发生的所有情况下都包含初始化是有意义的。在另一个平台上,复制一个无意义的值只会导致目的地保存一个无意义的值,然而,在没有任何副本最终用于任何实际目的的情况下,允许程序员省略初始化通常更有意义。该标准的作者没有努力说明在任何特定情况下什么是有意义的,因为他们期望编写实现的人应该能够进行良好的判断


    处理这种情况的最佳方法可能是编写一个宏,该宏接受一个变量,其展开将变量初始化为零(对于那些作者认为在复制未初始化变量时允许编译器跳转的实现,即使没有任何副本真正“用于”任何事情,也比保证复制变量的行为不会产生副作用更有价值)或者什么都不做(当使用一个即使没有无用的初始化也能保持在轨道上的实现时)。

    @tuple\u cat对其进行了测试,gcc没有抱怨
    -Wall
    (并且,对于额外的积分:)@PaulR Try
    -Winit self
    。就我目前所能研究的而言,当前的答案都没有抓住要点:习惯用法
    var x=x
    用于故意使用未初始化的变量并抑制gcc的警告。这独立于(可能是正确的)观察,它根据标准调用UB。现在我们只需要有人解释这在哪些情况下有用;)@IvayloStrandjev为什么要在这个特定的示例中使警告静音?它告诉您一个严重的错误。@M.M我不想要它
    char* acFilename = m_acFilename;
    
    $ cat foo.c
    int
    foobar(void)
    {
        int foo;
        return foo + foo;
    }
    $ cc -c -Wall -O2 foo.c
    foo.c: In function ‘foobar’:
    foo.c:6:13: warning: ‘foo’ is used uninitialized in this function [-Wuninitialized]
      return foo + foo;
             ~~~~^~~~~
    $ ed foo.c
    [...]
    $ cc -c -Wall -O2 foo.c
    $ cat foo.c
    int
    foobar(void)
    {
        int foo = foo;
        return foo + foo;
    }
    $ cc -c -Wall -O2 foo.c
    $ cc -v
    [...]
    gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12)
    $