C 库 - 在 C++ 中的使用:重新定义、不同的类型修饰符
C library - use in C++: redefinition, different type modifiers
我最近用纯 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 ... xxx\Projects\LibCSV\LibCSV\csv.h 10
C++ 处理 typedef 的方式是否与 C 不同?不知何故,...
Here 你的 MCVE 应该是这样的:
typedef struct T *T;
这是一个完整的 one-line 源文件,它重现了问题并且没有依赖项。没有宏,没有 headers,没有不必要的代码。
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
是一个 class(令人困惑的是,你在 typedef
本身做了!),你不能只给出一些其他类型(你正在尝试创建与 typedef
) 相同的名称。
无论如何,你所做的事情相当奇怪,让 CSV_T
意味着 struct CSV_T*
。我建议干脆不要这样做。
如果您只是坚持使用 typedef struct CSV_T CSV_T
那么这将适用于两种语言,但尝试使用相同的名称制作 不同的 类型就不行了去上班了。
C++ 标准的附录 C 说:
7.1.3
Change: A C++ typedef name must be different from any class type name declared in the same scope (except if the typedef is a synonym of the class name with the same name). In C, a typedef name and a struct tag name declared in the same scope can have the same name (because they have different name spaces).
Example:
typedef struct name1 { /.../ } name1; // valid C and C++
struct name { /.../ };
typedef int name; // valid C, invalid C++
Rationale: For ease of use, C++ doesn’t require that a type name be prefixed with the keywords class, struct or union when used in object declarations or type casts.
Example:
class name { /.../ };
name i; // i has type class name
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Semantic transformation. One of the 2 types has to be renamed.
How widely used: Seldom.
我最近用纯 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 ... xxx\Projects\LibCSV\LibCSV\csv.h 10
C++ 处理 typedef 的方式是否与 C 不同?不知何故,...
Here 你的 MCVE 应该是这样的:
typedef struct T *T;
这是一个完整的 one-line 源文件,它重现了问题并且没有依赖项。没有宏,没有 headers,没有不必要的代码。
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
是一个 class(令人困惑的是,你在 typedef
本身做了!),你不能只给出一些其他类型(你正在尝试创建与 typedef
) 相同的名称。
无论如何,你所做的事情相当奇怪,让 CSV_T
意味着 struct CSV_T*
。我建议干脆不要这样做。
如果您只是坚持使用 typedef struct CSV_T CSV_T
那么这将适用于两种语言,但尝试使用相同的名称制作 不同的 类型就不行了去上班了。
C++ 标准的附录 C 说:
7.1.3
Change: A C++ typedef name must be different from any class type name declared in the same scope (except if the typedef is a synonym of the class name with the same name). In C, a typedef name and a struct tag name declared in the same scope can have the same name (because they have different name spaces).
Example:
typedef struct name1 { /.../ } name1; // valid C and C++ struct name { /.../ }; typedef int name; // valid C, invalid C++
Rationale: For ease of use, C++ doesn’t require that a type name be prefixed with the keywords class, struct or union when used in object declarations or type casts.
Example:
class name { /.../ }; name i; // i has type class name
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Semantic transformation. One of the 2 types has to be renamed.
How widely used: Seldom.