c++ - 为什么我的 C 程序可以从 C++ 文件调用函数而不包含 header ?

标签 c++ c call extern

例如,假设我有以下文件:hello.cpp、hello.h 和 main.c

在 hello.cpp 中说我有以下内容:

#include "hello.h"
extern "C" void test_func(int &a, int b){
   some stuff   
}

在 hello.h 中我有以下内容:

#ifdef __cplusplus
extern "C" {

#endif
void test_func(int& a, int b);

#ifdef __cplusplus
}
#endif

这就是我困惑的地方。如果我在 main.c 中有以下内容:

#include "hello.h"
extern void test_func(int*, int);

那么这将无法正确编译。它告诉我 hello.h 文件中有错误,我认为这是因为 C 不支持按引用传递?我注意到,如果我将 hello.h 文件更改为“void test_func(int*a, int b)”,那么这将正确编译。

但是,如果我的 main.c 文件中没有 #include "hello.h",那么它也能正确编译。而且,即使不包含 hello.h,我也可以从 main.c 调用 test_func。声明函数原型(prototype)就足够了吗?为什么?如果我想包含 hello.h 是否意味着我必须使其与 C 兼容并且没有任何通过引用传递的函数?

对这一切都很陌生,所以提前感谢任何人的帮助。

最佳答案

用两个不同的原型(prototype)声明相同的 C 函数是未定义的行为。不要那样做。 (无论如何,这种特殊情况可能会“起作用”,因为典型的编译器通过将内存地址放在堆栈上来传递指针类型,并通过将内存地址放在堆栈上来传递引用类型。)

所以,是的,您当前的 hello.h 根本不能在 C 代码中使用。如果你想让一个函数跨越 C-C++“边界”,它应该有一个类似 C 的声明。 (除非它可以位于 C++ 端的命名空间中;此命名空间在 C 端被忽略。)

相反,您可以围绕 C++ 函数创建一个 C 包装器:

// hello.h
#ifndef HELLO_H_GUARD_
#define HELLO_H_GUARD_

#ifdef __cplusplus
void test_func(int &a, int b);

extern "C"
#endif
void test_func_c(int *a, int b);

#endif

// hello.cpp
void test_func(int &a, int b) {
    //...
}

extern "C"
void test_func_c(int *a, int b) {
    test_func(*a, b);
}

顺便说一下,您提到了一个“main.c”文件。混合 C 和 C++ 时,main 函数应位于 C++ 源文件中。如果您愿意,它可以只是一个调用“真正的”C main-like 函数的包装器。

关于c++ - 为什么我的 C 程序可以从 C++ 文件调用函数而不包含 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22211646/

相关文章:

c++ - unsigned-signed 下溢机制

c++ - 需要一个函数在用完有效值后继续减少值

c++ - 如何使用 opencv 库将 3D 矩阵的元素置零?

c++ - 我应该停止使用抽象基类/接口(interface),而是使用 boost::function/std::function 吗?

c - 嵌套结构的动态数组成员

python - python中如何通过调用文件中的函数名来打印文件名

javascript - [].forEach.call(...?

c++ - Qt:创建一个滚动条,后面有一个阴影,它包含最后一个值

c++ - 外部变量是否初始化为其默认值?

mysql - 在 C API 中检索 MySQL *con 值