gpt4 book ai didi

c++ - 外部 "C"或不外部 "C"[g++ vs cl]

转载 作者:太空狗 更新时间:2023-10-29 20:20:04 27 4
gpt4 key购买 nike

我正在将数值食谱 four1.c 与 Nayuki's FFT 进行比较.两者都是 C 版本,但我使用的是 C++ 驱动程序。为了进行比较,我正在使用 CL.exe 和 g++ 将两者编译(或更恰本地说,链接)到一个可执行文件中。两人似乎在争论是否对 four1 函数使用 extern "C",但似乎都不关心 Nayuki 的。我为 four1 创建了一个头文件,它检查 _WIN32 以便适本地切换,并且它有效,但似乎是一个完全不能接受的 hack。我该如何解决这个问题?

这是头文件:

#pragma once
#ifdef _WIN32
extern "C" void four1(float data[], unsigned long nn, int isign);
#else
void four1(float data[], unsigned long nn, int isign);
#endif

这是 CL 在没有 extern "C"的情况下所做的:

drvr.obj : error LNK2019: unresolved external symbol "void __cdecl four1(float * const,unsigned long,int)" (?four1@@YAXQAMKH@Z) referenced in function _main
drvr.exe : fatal error LNK1120: 1 unresolved externals

如果使用 extern "C",这就是 g++ 所做的:

/tmp/ccK1Hb2N.o: In function `main':
drvr.cpp:(.text+0x347): undefined reference to `four1'
collect2: error: ld returned 1 exit status

适用于 CL 的不适用于 g++,适用于 g++ 的不适用于 CL。至少对于这个文件。 Nayuki代码不存在这样的问题。

我尝试按照建议修改头文件,所以现在这里是 dfour1.h:

#pragma once
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
void dfour1(double data[], unsigned long nn, int isign);
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

g++ 没问题。 CL 不是。

>cl drvr.cpp dfour1.c fft.c carrier.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

drvr.cpp
Generating Code...
Compiling...
dfour1.c
fft.c
Generating Code...
Compiling...
carrier.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation. All rights reserved.

/out:drvr.exe
drvr.obj
dfour1.obj
fft.obj
carrier.obj
drvr.obj : error LNK2019: unresolved external symbol "void __cdecl dfour1(double * const,unsigned long,int)" (?dfour1@@YAXQANKH@Z) referenced in function _main
drvr.exe : fatal error LNK1120: 1 unresolved externals

顺便说一句,如果没有头文件,也会发生同样的情况,我只是添加:

extern "C" void dfour1(double data[], unsigned long nn, int isign);

到drvr.cpp文件,去掉头文件。 CL 仅在存在 extern "C" 时起作用,而 g++ 则不起作用。而删除 extern "C" 适用于 g++ 但不适用于 CL。

是的,我知道原始头文件是错误的,这就是问题所在。当我“正确”地做到这一点时,它不起作用,因此该帖子。当我制作一个“不正确”的头文件来检查正在使用哪个编译器时,它起作用了,这是令人讨厌的部分。简单地检查 C++ 是行不通的。

最佳答案

查看几乎任何系统 C 头文件,您都会看到如下代码:

/* C++ needs to know that types and declarations are C, not C++.  */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif

__BEGIN_DECLS

// some declarations

__END_DECLS

这是您自己的 header 中需要与 C 和 C++ 接口(interface)的模式。当然,除了你不应该使用前导下划线,因为它们是为系统内容保留的。

关于c++ - 外部 "C"或不外部 "C"[g++ vs cl],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54369779/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com