我在使用宏时遇到了问题,因为它们已被花括号替换。
由于我将需要针对不同的操作系统(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};
但是我不明白原因,我想保持代码尽可能整洁。有什么办法可以在数组定义中包含宏吗?
答案 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)