宏使用不需要的大括号替换自身

时间:2018-12-29 13:35:01

标签: c++ c++17

我在使用宏时遇到了问题,因为它们已被花括号替换。

由于我将需要针对不同的操作系统(WINDOWS,OSX,ANDROID,iOS)进行编译,因此我尝试将typedef用于基本的C ++类型,以轻松替换它们并测试性能。

由于我要进行大量的static_cast,所以我认为只有在需要宏时才能使用宏(CPU在我的软件中很重要)。因此,以这种方式,仅在类型不同时才执行static_cast,而不是像这样做奇怪的事情:

const int tv = 8;
const int tvc = static_cast<int>(8);

因此,如果是否启用FORCE_USE32,它将为其选择最佳版本

因此,当我执行以下操作时,使用默认编译器的Visual Studio 2017给我一个错误:

#ifndef FORCE_USE32
#define FORCE_USE32 0
#endif


#if FORCE_USE32
   typedef int s08;
    #define Cs08(v) {v}
#else
   typedef char s08;
   #define Cs08(v) {static_cast<s08>(v)}
#endif

// this line give me an error because Cs08 is replaced by {static_cast<s08>(1)} instead just static_cast<s08>(1)
std::array<s08, 3> myArray{Cs08(1), 0, 0}; 

我知道我可以在创建数组之前轻松解决创建变量的问题,

const s08 tempVar = Cs08(1);
std::array<s08, 3> myArray{tempVar, 0, 0}; 

但是我不明白原因,我想保持代码尽可能整洁。有什么办法可以在数组定义中包含宏吗?

1 个答案:

答案 0 :(得分:7)

您正在尝试解决非问题

const int tvc = static_cast<int>(8);

此处将不使用任何CPU周期。您认为当今的编译器有多愚蠢?即使没有优化,上面的转换也是无操作(无操作)。不会为演员表生成任何其他说明。

auto test(int a) -> int
{
    return a;
}

auto test_cast(int a) -> int
{
    return static_cast<int>(a);
}

未启用优化功能,这两个函数会生成相同的代码:

test(int):                               # @test(int)
        push    rbp
        mov     rbp, rsp
        mov     dword ptr [rbp - 4], edi
        mov     eax, dword ptr [rbp - 4]
        pop     rbp
        ret
test_cast(int):                          # @test_cast(int)
        push    rbp
        mov     rbp, rsp
        mov     dword ptr [rbp - 4], edi
        mov     eax, dword ptr [rbp - 4]
        pop     rbp
        ret

通过-O3他们得到:

test(int):                               # @test(int)
        mov     eax, edi
        ret
test_cast(int):                          # @test_cast(int)
        mov     eax, edi
        ret

回到编译器(实际上是优化算法)的智能程度,启用优化后,编译器可以做疯狂的事情,例如循环展开,将递归函数转换为迭代函数,删除整个冗余代码等等。等等。您正在做的是过早的优化。如果您的代码对性能至关重要,那么您需要对汇编,编译器优化和系统体系结构有一定的了解。然后,您不仅会盲目优化您认为缓慢的内容。首先编写代码以提高可读性,然后再进行概要分析。


解决宏问题:只需从宏中删除{}

#define Cs08(v) v
#define Cs08(v) static_cast<s08>(v)