【发布时间】:2023-02-26 00:51:42
【问题描述】:
我有一个可以在 MacOS 和 Linux 上编译的程序。在我的 makefile 中,我定义了一个变量:
# MAC
ifeq ($(UNAME), Darwin)
OS = APPLE
#LINUX
else
OS = LINUX
endif
INCLUDES = -Iincludes -Ilibft -I$(MLX_DIR) -D$(OS)
导致以下编译:
gcc -Wall -Wextra -Werror -O3 -Iincludes -Ilibft -I./minilibx_mms -DAPPLE -c srcs/parser/parser.c -o objs/parser/parser.o
gcc -Wall -Wextra -Werror -O3 -Iincludes -Ilibft -I./minilibx_mms -DAPPLE -c srcs/terminate/gameover_sys.c -o objs/terminate/gameover_sys.o
如您所见,我将 APPLE 作为宏传递,因此当我调用此函数时:
if (cub->mlx)
{
#ifdef LINUX
mlx_destroy_display(cub->mlx);
#endif
free(cub->mlx);
}
#ifdef 和#endif 之间的所有内容都应该在编译前删除,对吗?但是,唉,我从编译器那里得到了这个错误:
Call to undeclared function 'mlx_destroy_display'; ISO C99 and later do not support implicit function declarations clang(-Wimplicit-function-declaration)
该函数仅存在于库的 Linux 实现中。我对预处理器指令的理解哪里不正确?据我了解,当 LINUX 宏不存在时,应删除整个 #ifdef LINUX 部分。
【问题讨论】:
-
也许您包含的标题之一定义了该宏?
-
嗨格哈德!我确实注意到现在在标题中我有这个: /* OS CHECK */ #ifdef APPLE #define LINUX 0 #define ESC_KEY 53 但是,我认为将它定义为 0 意味着它是未定义的。显然不是这样?
-
@Hendrik No. 定义它 t
o0 表示它是定义的用于#ifdef/#ifndef/#if defined(Macro)支票。但是,如果您改用#if LINUX,那么未定义和 0 定义的 LINUX 都会导致#if分支被删除。 (这就是为什么我个人更喜欢#if而不是#ifdef)。 -
谢谢大家。你是对的,一个简单的#if LINUX 而不是#ifndef LINUX 就足够了。事后看来,这似乎很明显。
-
@Hendrik 这可能不是很明显。预处理器在其
#if条件中用 0 替换未定义的标记。所以#if some_undefined+3 == 3是一个分支。这就是为什么有时您会看到像((int)+OTHER_MACRO)宏定义这样的转换,这样这些宏也可以在#if条件语句中使用,它们变成((0)+something)。
标签: c c-preprocessor