代码之家  ›  专栏  ›  技术社区  ›  Juan JuezSarmiento

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

  •  0
  • Juan JuezSarmiento  · 技术社区  · 6 年前

    宏有问题,因为它们被大括号替换了。

    由于我需要编译不同的操作系统[Windows、OSX、Android、iOS],所以我尝试使用TyPulf来实现基本C++类型,以方便地替换它们并测试性能。

    由于我做了大量的静态转换,我认为我可以使用宏来完成它,只有当它需要时(CPU在我的软件上是至关重要的)。因此,只有当类型不同时才会执行静态\强制转换,而不是像这样执行奇怪的操作:

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

    因此,如果启用或不启用force_se32,它将为其选择最佳版本

    因此,使用默认编译器的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 回复  |  直到 6 年前
        1
  •  7
  •   bolov    6 年前

    你想解决一个非问题

    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)