【发布时间】:2019-03-14 09:26:16
【问题描述】:
在下面的片段中,我有一个 struct IndexError
当用户使用我的库出错时返回。我有一个类似函数的宏,它将一个指向IndexError* 的指针和一个枚举都称为INDEX_ERROR。
enum errors {
SUCCESS,
INVALID_ARGUMENT,
INDEX_ERROR
};
struct Error {
char error_buff[BUFSIZ];
};
typedef struct Error Error;
struct IndexError {
Error parent;
size_t invalid_index;
// etc.
};
typedef struct IndexError IndexError;
#define INDEX_ERROR(obj) ((IndexError*) obj)
我将如何使用它的一个例子是:
size_t pos = 4;
int IndexPointer* error = NULL;
int status = array_remove_item(my_array, pos, &error);
然后我检查状态。如果它没有返回SUCCESS,我会检查错误,因为那应该指向一个新创建的错误。
其中一个数组函数的实现可能如下所示:
int array_remove_item(Array* array, size_t pos, Error** error_out)
{
Error* error = NULL;
if(pos >= array->size) {
index_error_create(INDEX_ERROR(&error), pos); // use casting macro.
*error_out = error;
return INDEX_ERROR; // is this the macro or the value from the errors enum?
}
priv_array_remove_item(array, pos);
return SUCCESS;
}
所以我的问题是,在return INDEX_ERROR;,INDEX_ERROR 会从枚举中返回值,还是预处理器会因为我的命名不方便而咬我?
【问题讨论】:
-
宏替换发生在一个单独的阶段之前其他标识符通过编译器。 This translation phase reference 可能会有所帮助。
-
宏在编译之前得到扩展。因此,您的枚举值
INDEX_ERROR将被宏文本替换。但是,我希望预处理器会抱怨您在没有参数的情况下引用了宏。 -
不直接相关,但
_This _Sort的标识符保留给实现以供任何使用。你可以声明typedef struct Error Error;就好了。 -
另请注意,在 C(以及 C++,但将来只标记您实际编程的语言,因为 C 和 C++ 是两种非常不同的语言)中以下划线开头的符号和后跟一个大写字母(例如
_Error)在编译器和标准库的所有范围内保留。您通常不应自己定义此类符号。 -
@StoryTeller 编辑并删除了下划线
标签: c macros c-preprocessor