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

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

char * acFilename = acFilename; 

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

在块范围内,在C ++中,这是未定义的行为,因为右侧在变量初始化之前读取变量 (C ++ 14 [dcl.init] / 12)。

在块范围内,在C11中,这可能是未定义的行为或表现为未初始化的变量,具体取决于实现的各种细节和函数的其余部分, 请参见此处以进行详细分析。

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

在C中的文件范围内,它是一个约束违规; 静态变量必须具有常量表达式作为初始化程序,并且变量的值不能是常量表达式。

没有这个代码没有任何意义。 这可能是一个错字,也许有人打算使用

 char* acFilename = ::acFilename; 

要么

 char* acFilename = m_acFilename; 

或者是其他东西。

就目前而言,它充其量只是令人困惑和无益,可能是一个错误,因为有人想要使用不同的变量。

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

我只需将其初始化为NULL替换它。 这是一个坏习惯,不适用于其他编译器,并且NULL不能比不确定的值和未定义的行为更正确。

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

 $ 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) $ 

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

  1. 已接收的输入已导致变量被写入,并且还将导致代码在将来使用其值。

  2. 已接收的输入导致变量不被写入,但也会导致代码不使用其值。

如果某些编译器看到存在会导致变量无法写入的输入,并且存在会导致变量被读取的输入,则会发出尖叫声。 即使导致变量被读取的唯一输入也会导致它被写入,编译器可能也没有意识到这一点。 虽然可以通过无条件地初始化变量来使编译器的抱怨变得沉默,但是使用永远不会被实际使用的值来初始化变量的机器代码将不起作用。 因此,源代码构造会使编译器的抱怨无效但不会导致编译器生成无用的机器代码,因此可能优于需要生成无用机器代码的源代码构造。 在某些编译器中,自我初始化声明可以用于此目的。

如果一个类型有陷阱表示,那么编写初始化可能没有实际的替代方法,编译器可能会变成无用的机器代码,但如果一个类型没有陷阱表示,那么质量编译器应该强制程序员没有特别的理由要求他们不想要和不需要的无用代码。 然而,标准的作者并没有试图为各种类型做和不具有陷阱表示的平台设置不同的规则,而是推迟实施者对于特定目标平台和应用程序的哪种行为是明智的判断领域。

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

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