C 库 - 用于C++:重定义,不同的类型修饰符

C library - use in C++: redefinition, different type modifiers

本文关键字:类型 定义 用于 C++      更新时间:2023-10-16

我最近用纯C构建了一个CSV库。头文件如下所示:

  #ifndef CSV_H
  #define CSV_H
    #include "unicode/ustdio.h"
    #include "unicode/uchar.h"
    #include "unicode/ucsdet.h"
    #include "unicode/ustring.h"
    #define T CSV_T
    typedef struct T *T;
    extern T    CSV_new(char *filename);
    extern void CSV_free(T *csv);
    extern int  CSV_length(T csv);
    extern void CSV_print_info(T csv);
    extern UChar **CSV_get_header(T csv);
    extern UChar ***CSV_get_values(T csv);
    extern long CSV_get_num_columns(T csv);
    extern long CSV_get_num_lines(T csv);
    extern char *CSV_get_charset(T csv);
    #undef T
    #endif

结构CSV_T的实际定义是在代码文件中完成的,以隐藏实现。我经常使用纯C在不同的项目中使用该库,没问题。现在我想在使用C++构建的 GUI 应用程序中重用代码,并收到以下错误消息:

Error   C2373   'CSV_T': redefinition; different type modifiers     ... xxxProjectsLibCSVLibCSVcsv.h    10  

C++处理与 C 不同的 typedef 吗?不知何故令人困惑,...

以下是您的 MCVE 应该是什么样子:

typedef struct T *T;

这是一个完整的单行源文件,可重现问题且没有依赖项。没有宏,没有标头,没有不必要的代码。

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:1:19: error: conflicting declaration 'typedef struct T* T'
 typedef struct T *T;
                   ^
main.cpp:1:16: note: previous declaration as 'struct T'
 typedef struct T *T;
            ^

它在 C 中工作的原因是T还不是结构的名称;你需要struct前缀。

在C++中,这不是真的,因为首先不需要struct前缀。一旦你声明T是一个类(令人困惑的是,你在typedef本身就是这样做的!),你不能只给其他类型(你试图用typedef创建的那个)相同的名称。

反正你在做什么很奇怪,CSV_T的意思是struct CSV_T*.我建议干脆不要这样做。

如果您只是坚持使用typedef struct CSV_T CSV_T那么这将适用于两种语言,但尝试使用相同的名称制作不同的类型是行不通的。

C++标准的附录C说:

7.1.3

更改:C++ typedef 名称必须不同于在同一作用域中声明的任何类类型名称(除非 typedef 是具有相同名称的类名的同义词)。在 C 中,在同一作用域中声明的 typedef 名称和结构标记名称可以具有相同的名称(因为它们具有不同的命名空间)。

例:

typedef struct name1 { /.../ } name1; // valid C and C++
struct name { /.../ };
typedef int name; // valid C, invalid C++

理由:为了便于使用,C++ 在对象声明或类型强制转换中使用时,不要求类型名称以关键字 class、struct 或 union 为前缀。

例:

 class name { /.../ };
 name i; // i has type class name

对原始特征的影响:删除语义明确定义的特征。

转换

难度:语义转换。必须重命名 2 种类型之一。

使用范围有多广:很少。