【问题标题】:Is there a way to instruct a C++ compiler to skip rest of current file?有没有办法指示 C++ 编译器跳过当前文件的其余部分?
【发布时间】:2011-10-19 17:47:23
【问题描述】:

有时必须有条件地编译某些功能。例如,class Logger 仅在 WITH_LOGGING 宏为 #defined 时使用:

// Logger.cpp
#ifdef WITH_LOGGING
#include <Logger.h>
// several hundred lines
// of class Logger
// implementation
// follows
#endif

这不是很方便 - 除非读者滚动浏览文件,否则他无法确定匹配的 #endif 是否位于文件末尾,因此整个文件内容与 #ifdef 一起排除。我更喜欢这样的东西:

// Logger.cpp
#ifndef WITH_LOGGING
#GetOutOfThisFile
#endif
#include <Logger.h>
// several hundred lines
// of class Logger
// implementation
// follows

因此很明显,一旦WITH_LOGGING 不是#defined,编译器就会跳过文件的其余部分。

类似的东西在 C++ 中可能吗?

【问题讨论】:

  • 你不能评论一下吗? //If this is not defined nothing in here gets compiled 似乎是我认为的重点。
  • 这基本上就是包含守卫所做的事情,而且几乎没有人会因为在文件开头有一个 #ifdef 而在文件末尾为几乎每个头文件都有一个 #endif 而感到困扰.
  • 这是(原因之一)文本编辑器有块折叠的原因。
  • 我认为,如果您查看代码并没有立即意识到尽管最后没有 #endif,但它并未包含在内,这会更加令人困惑。
  • @Nicol Bolas:我并没有说没有人被包含守卫本身所困扰,我说没有人被文件开头的#ifdef#endif 所困扰根据包含警卫的要求在文件末尾。据我所知,#pragma once 的发明是为了让您不必为每个头文件都想出一个唯一的宏名称,而不是因为 #ifdef/#endif 的事情。

标签: c++ visual-c++ compiler-construction c-preprocessor


【解决方案1】:

澄清这一点的一种简单方法是将实现放在另一个文件中:

文件 Logger.cpp:

#ifdef WITH_LOGGING
 #include <Logger.h>
 #include "logger.impl"
#endif

文件 logger.impl:

// several hundred lines
// of class Logger
// implementation
// follows

【讨论】:

  • 我很确定指令的 # 部分必须位于文档的第一列。
  • @in silco:# 必须是一行中的第一个非空白字符。在预处理控件以及嵌套数据和代码中,缩进大大增加了可读性。
  • +1 可以,我已经看到很多地方都这样做了。
  • @wallyk:我的立场是正确的。但是我从来没有说过不应该有缩进。我见过有人做类似#ifdef/# include 的事情(注意#include 之间的空格),所以我认为在第一列需要# 就是这种情况。
  • @wallyk, In silico:在传统的预处理中,不能有前导空格 - # 必须在第一列(但在 # 之后允许空格)。见gcc.gnu.org/onlinedocs/cpp/…;在 ISO 预处理器语言中(请参阅 gcc.gnu.org/onlinedocs/cpp/… ),允许前导空格和尾随空格。因此,最安全的选择是仅使用尾随空格,例如# include "logger.impl"
【解决方案2】:

您为什么要排除该文件的内容?如果我理解正确,如果未设置定义,则不会使用其中的代码。在这种情况下,链接时优化应该从可执行文件中删除这些函数。

如果您有从其他库覆盖的函数,这将不起作用,但对于常规情况(并且很可能用于日志记录),这就足够了。在 GCC 中,这是编译器的 --ffunction-sections 和链接器的 --gc-sections。 Visual Studio 应该有类似的标志,但我不知道它们是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2012-09-16
    • 2014-02-17
    • 2010-10-06
    相关资源
    最近更新 更多