【问题标题】:Defining keyword-like macros just for improving code readablity [closed]定义类似关键字的宏只是为了提高代码的可读性[关闭]
【发布时间】:2014-10-17 21:03:29
【问题描述】:

如果定义类似关键字的宏可以提高代码的可读性,是不是错了?

例如,IMPLICIT 宏:

#define IMPLICIT /* IMPLICIT constructor(parameters...); */

struct X
{
    explicit X();
    IMPLICIT X(int i);
    IMPLICIT X(std::sting s);
    explicit X(const char* ch);
};

代替:

struct X
{
    explicit X();
    X(int i);
    X(std::sting s);
    explicit X(const char* ch);
};

注意事项:无论代码可读性如何,IMPLICIT 宏的定义都可以更改为简单地禁用所有隐式构造函数或...,以供将来维护。

编辑:我的示例并不重要,我的问题不是针对它的,我删除了block 宏示例。

【问题讨论】:

  • 但是你并没有提高代码的可读性。
  • 我投票结束这个“主要基于意见”,因为这是主观的。事实上,我同意 juanchopanza,这对我来说似乎很可怕
  • 它们并没有提高可读性,因为读者需要在继续之前找到宏的定义。不能信任宏及其名称。
  • 简化或澄清代码的宏可能会有所帮助,特别是如果它们有助于在特定项目中重复完成的某些事情 - 封装常见的错误处理策略等。不过,这些例子很疯狂,所以很难具体回答(免责声明或否)。
  • 视情况而定。上面的宏很糟糕,增加了冗长和冒着名称冲突的风险。但是在我看来,可以大大减少冗长性、封装实际上无法抽象的样板代码的宏是可以的,只要您使用全部大写名称和相对唯一的前缀。

标签: c++ macros code-readability


【解决方案1】:

很难找到好的示例,其中无法避免用于提高可读性的宏。

这是我能想到的最好的例子(来自 Linux 内核):

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

例子:

struct book {
  char title[100];
  char author[100];
};

// ...
printf("%lu\n", FIELD_SIZEOF(struct book, title)); // prints 100

(不知道这个宏在C++中能不能避免。)

除此之外,我认为宏在用于代码生成以消除样板代码时有时可以提高可读性。

【讨论】:

  • 如今在 C++ 中,您可以简单地使用 sizeof。此外,宏在技术上可能是未定义的行为。
  • 我澄清了我的问题是关于类似关键字的宏。
【解决方案2】:

如上所述,您的宏不会提高可读性。有人可能想知道BLOCKIMPLICIT 是什么意思,认为它们执行某些特殊功能,而实际上它们并没有。它似乎更适合评论或重构。在像 Visual Studio 这样的 IDE 中,您可以折叠代码行(隐藏/显示它们)或将它们分组到文档块中(即#REGION)。什么都不做的宏只会给你的代码增加噪音。

【讨论】:

    【解决方案3】:

    我最好的宏是日志记录宏:

    #define SYSTEM_FAILURE(code, comment) \
    { \
        System_Failure(code, comment, __FILE__, __FUNCTION__, __LINE__); \
    }
    

    宏是插入遇到故障的文件名、函数名和行号的最简单方法。

    除了这个宏,我们店里没有。

    【讨论】:

      【解决方案4】:

      定义类似关键字的宏只是为了提高代码的可读性

      我认为这是可以接受的。但正如 Marco 所说,它相当主观。


      我认为增强可读性的宏示例是 C++ 和 NOTHROW。奇怪的是,指定throw() 意味着函数不会抛出;并反对throw (SomeException),这意味着函数可能会抛出异常。当它不抛出时,声明 throw() 没有什么直观的。

      Stack Overflow 上有很多关于它的讨论:


      Microsoft 定义了INOUTINOUT 以帮助提高可读性和可用性。宏修饰函数参数并且被定义为空。例如,您可能会看到(我手边没有具体的 Microsoft 示例):

      // Process foo. Reuse baz if possible; reallocate if needed and return size.
      // Return TRUE/FALSE as success/failure. Return an error code if result is FALSE.
      int FooBarBaz(IN char* foo, IN int flen, INOUT char** baz, INOUT int* blen, OUT int* err);
      

      相关:宏有助于抽象平台差异。例如,从共享对象(Unix 和仿制品)或动态链接库 (Windows) 导出函数。


      相关:宏有助于抽象配置差异。例如,ASSERT 在调试和发布配置中的含义或实现。


      相关:劫持关键字可能会有所帮助。例如,在测试期间将 C++ 的 protectedprivate 重新定义为 public 可能会有所帮助,因此可以针对通常无法访问的方法编写测试用例。

      【讨论】:

      • 谢谢你的例子:)
      猜你喜欢
      • 2010-10-07
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 2015-08-10
      • 2013-08-01
      • 2021-11-19
      相关资源
      最近更新 更多