在 C++ 项目中使用 flex/bison 时避免“警告 C4005: 'INT8_MIN': 宏重新定义”

问题描述 投票:0回答:1

我有一个使用 flex/bison 的 C++ 项目。

词法分析器生成的代码包括以下部分:

/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */

#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L

#include <inttypes.h>
typedef int8_t flex_int8_t;
// ... more typedefs here

#else

typedef signed char flex_int8_t;
// ... more typedefs here

/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN               (-128)
#endif
// ... more defines here

#endif /* ! C99 */

Windows 编译会警告您所有已在

stdint.h
中定义的整数类型(例如
Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\stdint.h(49,1)
)。

我知道发生这种情况是因为 C++ 编译未设置

_STDC_VERSION__

我尝试将其设置为编译标志(

/D___STDC_VERSION__:199901L /D__STDC_VERSION__:199901L
),但这没有帮助(如果它确实有效,它也会看起来很脏)。

有办法避免这些警告吗?例如。以其他方式设置

__STDC_VERSION__
。或者对 Flex 生成的代码的那部分有更多的控制权?

c++ c bison flex-lexer
1个回答
0
投票

我在开发自己的 Flex + Bison 项目时实际上遇到了同样的问题。

问题与

__STDC_VERSION__
的值无关。请注意,您收到的警告是针对 macro 重新定义的,例如对于
INT8_MIN
等,您可以在查看源文件时看到,例如

/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN               (-128)
#endif

/* ... */

这些

INT8_MIN
INT16_MIN
等宏已经在
stdint.h
中定义,所以我猜测您看到此警告的原因是因为您的
.l
文件有一个用
%{
 括起来的块}%
在定义部分中包含一些
#include
指令,其中之一是传递性地包含
stdint.h

您可以通过将以下内容添加到

.l
文件的定义部分来轻松解决此问题:

%top{
  #include <stdint.h>
}

如果将 Flex 输出编译为 C++,则可以用

<cstdint>
替换。为什么这是必要的,因为至少对于我正在使用的 Flex 2.6.4,具有
%{
}%
的内容会在 INT8_MIN
INT16_MIN
等宏之后复制到生成的源中。已定义,因此任何传递包含
#include
stdint.h
都会重新定义这些宏,这就是 MSVC 所抱怨的。
相反,

%top

块,如

Flex文档
中所述,将在任何Flex定义之前将其内容复制到生成的源文件的top。您不需要将所有 #include 指令放在顶部块中,除非,例如对于
stdint.h
,这样做有一些特殊的原因。
    

© www.soinside.com 2019 - 2024. All rights reserved.