C与C ++编译不兼容-未命名类型

时间:2018-06-27 11:03:39

标签: c++ c gcc g++

我正在尝试将供应商的库与我的C ++应用程序结合使用。该库主要基于C,extern "C"选项通常不是问题,但是我遇到了C ++编译器不接受的问题。

我将代码简化为以下示例文件。 header.h代表供应商库中的头文件,main.c / cpp是我自己的文件。我真正的应用程序是C ++应用程序,因此我想使其与main.cpp一起使用。

header.h(注意行u64 u64;):

#ifndef HEADER_H
#define HEADER_H

#include <stdint.h>

typedef uint64_t u64;

union teststruct {
    u64 u64;
    struct {
        u64 x:32;
        u64 y:32;
    } s;
};

#endif

main.c:

#include <stdio.h>
#include "header.h"

int main() {
    union teststruct a;
    a.u64=5;
    printf("%x\n", a.u64);

    return 0;
}

main.cpp(与main.c相同,但带有一个额外的extern "C"语句):

#include <stdio.h>

extern "C" {
#include "header.h"
}

int main() {
    union teststruct a;
    a.u64=5;
    printf("%x\n", a.u64);

    return 0;
}

使用该行编译main.c

gcc -o test main.c

编译没有问题。但是,使用g ++编译器和

命令来编译C ++版本
g++ -o test main.cpp

给出以下编译器错误:

In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64’ does not name a type
         u64 x:32;
         ^
header.h:12:9: error: ‘u64’ does not name a type
         u64 y:32;
         ^

问题在于,供应商为类型和变量名称使用了相同的名称(u64),这似乎是一个坏主意,但gcc显然接受了它。我不想更改库(即header.h),因为它很大,这在代码中经常发生,有时我会对其进行更新。有没有办法让g ++接受这种组合,还是有办法修改main.cpp以使其在不更改header.h的情况下编译

3 个答案:

答案 0 :(得分:48)

teststruct定义了C ++的范围。您可以形成合格的ID teststruct::u64。因此,名称查找的语言规则解决了这一问题,从而允许类和联合的成员在外部范围中隐藏标识符。引入u64 u64;后,不合格的u64不能引用全局::u64,只能引用成员。而且成员不是类型。

在C union teststruct中没有定义范围。该字段只能在成员访问中使用,因此永远不会发生冲突。因此,该字段无需隐藏文件作用域类型标识符。

据我所知,您没有采取任何措施轻松解决此问题。该库(是完全有效的C库),不是有效的C ++库。与使用newtry作为变量名没有什么不同。需要进行调整。

答案 1 :(得分:39)

似乎您的头文件在C ++中是非法的,因此无法在编译为C ++的代码中#include对其进行Wrapper.h。如果您无法更改库头文件中的内容(例如,向您的库供应商投诉),那么最直接的选择是在库周围编写与C ++兼容的精简包装:

要针对C标头隔离C ++代码,请创建Wrapper.c.h,其中header.h有效地包含在C ++中,但不是包括.c,并提供库交互所需的所有类型和功能。然后,在#include "header.h"中,您可以Action.c(181): Error -26377: No match found for the requested parameter "c_abcdef". Either the specified boundaries were not found in the response or the matched text is longer than current max html parameter size of 999999 bytes. The total length of the response is 50472 bytes. You can use "web_set_max_html_param_len" to increase the max parameter size. [MsgId: MERR-26377] Action.c(181): Error -26377: No match found for the requested parameter "c_trRef". Either the specified boundaries were not found in the response or the matched text is longer than current max html parameter size of 999999 bytes. The total length of the response is 50472 bytes. You can use "web_set_max_html_param_len" to increase the max parameter size. [MsgId: MERR-26377] 并实现所有调用(以及在类型之间安全转换所需执行的所有操作)。显然,这必须编译为C,而不是C ++。

答案 2 :(得分:3)

如果仅是您提到的C与C ++之间的不兼容性,那么您应该能够以编程方式将header.h转换为与C ++兼容的头文件,并将其命名为header.hpp。然后您可以用相同的方式转换较新的版本。

编译器错误告诉您有关应更改的内容和位置的所有信息:

header.h:11:9: error: ‘u64’ does not name a type
  1. 打开header.h;
  2. 寻找位置11:9;
  3. 在此处插入::
  4. 重复所有does not name a type错误。

一些字符串处理就完成了。

PS:C到C ++转换器也可以做到这一点。