【问题标题】:I compiled this seemingly incorrect code, but I don’t understand why我编译了这个看似不正确的代码,但我不明白为什么
【发布时间】:2018-11-13 02:38:34
【问题描述】:

我正在一台 linux 机器上学习 C++。我刚试过“int i();”声明一个函数,但我忘了定义它。但令我惊讶的是,这段代码可以编译并输出1。我感到很困惑。我尝试了“int I{};”,它仍然编译没有错误。请帮忙解释一下。提前致谢。

 //test1.cpp
#include <iostream>
int main(void)
{
    int i{};
    std::cout << i << std::endl;
    return 0;
}

g++ test1.cpp
./a.out
Output is: 0

//test2.cpp
#include <iostream>
int main(void)
{
    int i();
    std::cout << i << std::endl;
    return 0;
}

g++ test2.cpp
./a.out
Output is : 1

【问题讨论】:

  • 如果您不在代码中的任何位置调用该函数,那很好。否则,您将在链接时收到错误,因为链接器将无法找到函数定义
  • 感谢您的快速回复。输出呢?为什么输出是1?还有“int i{};”。这是什么意思?
  • @RaymondChen 感谢您推荐的文章。那么“int i {};”呢?这个语法有什么作用?

标签: c++


【解决方案1】:

在您的第一个示例中,您定义了一个名为 i 的变量,并对其进行值初始化,对于 int 而言,这意味着零初始化。

int i{}; // defines i, initialised to zero

在第二个示例中,您声明了一个名为 i 的函数,它不接受任何参数,并返回 int

int i(); // declares a function

当你打印这个时:

std::cout << i << std::endl;

i 首先转换为booli 衰减为函数非空指针,然后变为true),然后打印为整数,这就是您得到1 的原因。编译器可以在没有i 定义的情况下进行这种转换(因为结果总是true),这就是你没有出现链接器错误的原因。

如果您的意图是调用此函数并打印结果,则需要使用i()

std::cout << i() << std::endl;

这当然需要i的定义。

【讨论】:

  • 很好的答案。谢谢。完全同意这个解释。
【解决方案2】:

在您的代码中:

//test1.cpp
#include <iostream>
int main(void)
{
    int i{};
    std::cout << i << std::endl;
    return 0;
}

你实际上并没有声明一个函数而不定义它。 main() function 中的代码行 int i{};variabletype int 名为 i 并且您正在使用 brace initializer list 来初始化变量 i 没有任何值,在大多数情况下可能是 0,但可能因 compiler 而异。

//test2.cpp
#include <iostream>
int main(void)
{
    int i();
    std::cout << i << std::endl;
    return 0;
}

在这种情况下,基本上是一样的。你在main() 内,并且根据"you can not declare-define a function within a function" 语言的规则,所以这会导致declaration - definitionvariable。这里唯一的区别是你没有使用brace initializer list,你在这里使用的是ctorconstructor,称为值初始化。同样,您没有向它传递任何值,在您的情况下,它分配了任意值 1

现在,如果您的代码如下所示:

#include <iostream>

int i();

int main() {
     std::cout << i() << '\n';
     return 0;
}

这将无法编译,因为 function ideclared 而不是 defined。但是,如果您这样做:

#include <iostream>

// The text in quotes is not meant to be a string literal. It
// is the message of the text that represents any integer X.
int i() { return /*"some int value"*/ 1; }

int main() {
    std::cout << i() << '\n';
    return 0;
}

这将完美地编译和运行,因为 function i 既是 declared 又是 defined

【讨论】:

  • 您为什么选择return "some int value" 而不是实际的 int 值?说它可以正常编译是一种误导,因为将字符串文字转换为整数至少应该会产生警告。
  • "在大多数情况下为 0,但可能因编译器而异。"它可能不会因编译器而异。是required to initialize to zero
  • @paddy 我指的不是字符串文字。我使用字符串文本来表示任何整数值;阅读文本!反正我会更新的。
  • 另外,T() 被称为值初始化,如果它没有默认构造函数,它会给你一个零初始化对象。
  • @francis,如果操作不能做到,为什么要编译?答:你可以声明一个函数(一个函数定义有一个主体),打印一个函数名将地址转换为布尔值并打印 1。
猜你喜欢
  • 2012-05-23
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2016-12-07
相关资源
最近更新 更多