【问题标题】:Main can not call a function: function was not declared in this scopeMain 无法调用函数:函数未在此范围内声明
【发布时间】:2014-04-03 08:01:48
【问题描述】:

我正在将 C 文件更改为 C++ 文件(最终将其与 C 程序集成)。我对 C++ 非常陌生,事实上这是我第一次接触它。我有一个 test.cpp 文件,它声明函数 main 和 hello 如下:

#include "test.h"

int main()
{
    hello ();
    return 0;
}

void hello()
{
    std::cout << "Hello there!" << endl;
}

test.h文件声明如下:

#include <iostream>

extern "C" void hello();

当我使用 g++ test.cpp 编译程序时,我收到错误“hello is not declared in this scope”。

有什么建议吗?

另外,在哪里可以找到 C++ 类及其函数的 API?

【问题讨论】:

  • 你发出的命令是什么?
  • 所以如果一个 C 程序,比如 myprog.c,需要调用函数 hello(),我会在 myprog.h 中将该函数声明为 extern "C" void hello?
  • 从 C 调用 C++ 很难,至少比从 C++ 调用 C 更难。最好将不需要 c++ 的所有函数放在单独的 .c 源文件中,以便将它们编译为 C,并从 C++ 源文件中声明它们为 extern "C"。在 .h 文件中的“extern C”周围放置一些#ifdef __CPLUSPLUS,这样您就可以从两种语言中包含它们;检查标准包含文件以获取示例。
  • 感谢您提供完整的可编译测试用例,但能否请您发布您遇到的实际错误的全文?
  • -1 您问题中的代码与错误信息不符

标签: c++ c


【解决方案1】:

我认为您可能误读了错误消息。应该导致错误的唯一错误是您没有将endl 限定为std::。您确定错误消息不是关于 endl 的吗?

编译您的完整测试用例,我得到以下信息:

$ g++ test.cpp
test.cpp: In function ‘void hello()’:
test.cpp:11:37: error: ‘endl’ was not declared in this scope
      std::cout << "Hello there!" << endl;
                                     ^
test.cpp:11:37: note: suggested alternative:
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from test.h:1,
                 from test.cpp:1:
/usr/include/c++/4.8/ostream:564:5: note:   ‘std::endl’
     endl(basic_ostream<_CharT, _Traits>& __os)
     ^

通过将std:: 添加到endl 来修复错误,修复所有编译和链接错误,并按预期提供hello C 语言链接。

(注意,将extern "C" 添加到函数hello 的定义中并没有什么坏处——而且可能更清楚——但只要第一个可见声明声明了正确的语言链接就没有必要。 )

【讨论】:

    【解决方案2】:

    问题是您在包含文件中声明它extern "C",但它在 hello.cpp 源文件中,因此它将被编译为 c++,而不是 c。

    【讨论】:

    • 这是错误的。该定义不会改变hello 的语言链接,它仍然与最初声明的C 语言链接保持一致。原始声明在定义处可见。
    【解决方案3】:

    您应该完全删除extern "C"
    使用标准命名空间。

    但如果你必须将函数编译为extern "C",则不需要你把它放在函数定义之前,只需要声明,你已经完成了。
    但是,如果您想将它添加到声明和定义中,您可以这样做。

    例子:

    #include "test.h"
    
    using namespace std;    
    
    int main()
    {
        hello ();
        return 0;
    }
    
    void hello()
    {
        cout << "Hello there!" << endl;
    }
    

    【讨论】:

    • 好吧,他在包含文件中做到了。
    • 外部不是问题;它在 c++ 源文件中,因此将被编译为具有 c++ 签名;但包含文件暗示了一个 c 签名。
    • 所以如果我删除关键字 extern "C" 并且如果一个 C 程序,比如 myprog.c,需要调用函数 hello(),我会在 myprog.h 中将 hello 声明为 extern "C “无效你好?
    • @DavidOtano 如果您删除 extern "C",您的答案中的程序会以相同的含义编译。那么,您在回答中究竟声称什么?
    • 你错了。正如查尔斯指出的那样,正如我在之前的评论中所说,如果您删除 extern "C",您答案中的程序将具有相同的含义。所以,再一次,你在回答中声称什么。
    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    相关资源
    最近更新 更多