【问题标题】:C pre-processor how to treat function macro as stringC预处理器如何将函数宏视为字符串
【发布时间】:2016-09-22 08:12:55
【问题描述】:

我正在使用 mingw 在 OSX for Windows 上编译 C++ 代码。 C++ 代码是自动生成的,包括 MS Visual Studio 特定的代码:

class __declspec(novtable) SomeClass

当我编译时,我收到很多警告:

warning: ‘novtable’ attribute directive ignored [-Wattributes]

我想禁止显示这些警告。 Mingw 不支持 -Wno-microsoft 选项,所以我想我可以让 __declspec(notable) 被视为指向空字符串的标识符并让预处理器将其删除。

即

#define __declspec(novtable) 

但是,这被视为对 __declspec() 宏的重新定义,这不是所需的行为。

有没有办法让预处理器将__declspec(novtable) 视为标识符,或者以其他方式抑制此警告? (不能修改有问题的自动生成代码)。

【问题讨论】:

  • 您想保留其他__declspec 并忽略novtable 吗?
  • 为什么不能修改生成的代码?在代码上运行sed(或awk)会相当方便。
  • 我很想修改代码,但它是自动生成的,需要保持不变,以便可以在多个平台上构建。其他人可能希望使用 VC 代码进行构建。

标签: c++ c-preprocessor


【解决方案1】:

大概编译器有这个定义

#define __declspec(x) __attribute__((x))

并且还可以识别某些(不是全部)Microsoft 特定属性,例如 dllexport 和 dllimport。仅当上述假设为真时,以下内容才有意义。

你可以使用

 #undef __declspec // to suppress a meessage about macro redefinition
 #define __declspec(x) // nothing

(也许适合#ifdefed 以免破坏与 MSVC 的兼容性)。

这将杀死整个__declspec 功能,而不仅仅是__declspec(novtable)。如果这不是您需要的,请继续阅读。

如果你只需要杀死__declspec(novtable) 并保持所有其他属性不变,试试这个

#define novtable // nothing

__attribute__ 指令可能包含一个可能为空的属性列表,因此__declspec(novtable) 可能会转换为__attribute__(()),这完全可以。这也将终止标识符novtable 的所有其他出现。如果它确实发生在任何其他情况下,这不太可能但有可能,则此选项对您不起作用。

另一种可能性是接管整个功能。

#undef __declspec
#define __declspec(x) my_attribute_ # x

#define my_attribute_dllexport __attribute__((dllexport)) // or whatever you need
#define my_attribute_dllimport __attribute__((dllimport)) // or whatever you need
// ... same for all attributes you do need

#define my_attribute_novtable // nothing
// ... same for all attributes you don't need

【讨论】:

  • 这是这样钝器......!
  • @LightnessRacesinOrbit 嗯?
  • 你杀死了整个后续代码的整个 __declspec 功能,假设它首先是一个宏。
  • @LightnessRacesinOrbit 这就是重点。 C++ 中没有这样的特性。
  • 嗯。我想。 OP 专门询问__declspec(novtable) 但是,现在你提到它......
【解决方案2】:

用一些宏定义你的__declspec(novtable):

 #define DECL_SPEC __declspec(novtable)  

之后,您可以将其用作:

 class DECL_SPEC SomeClass 

并在需要时将DECL_SPEC 重新定义为空:

 #ifdef __MINGW32__
 #define DECL_SPEC
 #else
 #define DECL_SPEC __declspec(novtable)
 #endif

【讨论】:

  • 这不是倒退吗?他不想使用class DECL_SPEC,他想在生成的代码中忽略__declspec(novtable)而不发出警告。 (感觉就像您将 #define 参数的顺序与 typedef 参数顺序混淆了。)
  • @Rup 不,这根本不是倒退。这个答案的意思是:“不要在您的代码中生成__declspec(novtable),而是生成DECL_SPEC。然后,您可以根据需要将#define DECL_SPEC 生成或不生成任何内容。
  • 不确定如何忽略警告,@John 可以尝试#pragma GCC diagnostic ignored "-Wattributes"
  • 好吧,这更有意义,尤其是现在您已经修复了 #define 行。但这仍然在修改生成的代码,如果以一种更可口的方式,NO_VTABLE 将是一个更好的宏名称。
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 2012-07-21
  • 2011-03-26
  • 2019-06-21
  • 2017-09-18
  • 2011-11-28
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多