是否可以打印出C+的大小+;在编译时初始化? 在编译时可以判断C++类的大小吗?< /P>
我似乎记得一个模板元编程方法,但我可能错了是否可以打印出C+的大小+;在编译时初始化? 在编译时可以判断C++类的大小吗?< /P>,c++,C++,我似乎记得一个模板元编程方法,但我可能错了 抱歉,没有说得更清楚-我希望在生成输出窗口中打印大小sizeof有什么问题?这应该适用于对象和类 void foo( bar* b ) { int i = sizeof bar; int j = sizeof *b; // please remember, that not always i==j !!! } 编辑: 这就是我想的例子,但由于某种原因,它不起作用。谁能告诉我怎么了 #include <iostream> u
抱歉,没有说得更清楚-我希望在生成输出窗口中打印大小sizeof有什么问题?这应该适用于对象和类
void foo( bar* b )
{
int i = sizeof bar;
int j = sizeof *b;
// please remember, that not always i==j !!!
}
编辑:
这就是我想的例子,但由于某种原因,它不起作用。谁能告诉我怎么了
#include <iostream>
using namespace std;
class bar {
public: int i;
bar( int ii ) { i = ii; }
virtual ~bar(){ i = 0; }
virtual void d() = 0;
};
class bar2: public bar {
public: long long j;
bar2( int ii, long long jj ):bar(ii){ j=jj; }
~bar2() { j = 0; }
virtual void d() { cout << "virtual" << endl; };
};
void foo( bar *b )
{
int i = sizeof (bar);
int j = sizeof *b;
cout << "Size of bar = " << i << endl;
cout << "Size of *b = " << j << endl;
b->d();
}
int main( int arcc, char *argv[] )
{
bar2 *b = new bar2( 100, 200 );
foo( b );
delete b;
return 0;
}
sizeof()确定编译时的大小
它在编译时才工作,所以你不能在预处理器中使用它。有操作符
sizeof(int)
,sizeof(char)
,所以我认为有可能调用类似于sizeof(MyClass)
的函数来回答更新后的问题——这可能有些过分了,但它会在编译时打印出类的大小。VisualC++编译器中有一个未记录的命令行开关,它将显示类的完整布局,包括它们的大小:
该开关是/d1reportSingleClassLayoutXXX,其中XXX对类名执行子字符串匹配
如果确实需要在编译器输出中获取sizeof(X),可以将其用作不完整模板类型的参数:
template<int s> struct Wow;
struct foo {
int a,b;
};
Wow<sizeof(foo)> wow;
$ g++ -c test.cpp
test.cpp:5: error: aggregate ‘Wow<8> wow’ has incomplete type and cannot be defined
template-struct-Wow;
结构foo{
INTA,b;
};
哇哇;
$g++-c test.cpp
test.cpp:5:错误:聚合“Wow Wow”的类型不完整,无法定义
以下是一个产生警告而非错误的版本:
/** Compile-time sizeof as a warning so
compilation can continue */
struct TestStruct
{
int i1;
float f1;
const char* pchar1;
double d1;
char c1;
void* pv1;
bool b1;
};
template<unsigned int n>
struct PrintNum {
enum { value = n };
};
template<int number>
struct _{ operator char() { return number + 256; } };
#define PRINT_AS_WARNING(constant) char(_<constant>())
int main()
{
PRINT_AS_WARNING(PrintNum<sizeof(TestStruct)>::value);
return 0;
}
编辑(2020年6月3日)
这个技巧适用于所有C编译器。对于Visual C++:
struct X {
int a,b;
int c[10];
};
int _tmain(int argc, _TCHAR* argv[])
{
int dummy;
switch (dummy) {
case sizeof(X):
case sizeof(X):
break;
}
return 0;
}
------生成已启动:项目:cpptest,配置:调试Win32------cpptest.cpp c:\work\cpptest\cpptest\cpptest.cpp(29):错误C2196:已使用大小写值“48”=======生成:0成功,1
失败,0是最新的,0已跳过==========
对于其他只打印“重复大小写值”的编译器,请参见我对该问题的回答:
然而,另一个导致VC++2010编译器抱怨编译时整数使用错误的技巧:
// cpptest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
struct X {
int a[11];
char c[2];
};
void proc1(void* s[1]) {
}
int _tmain(int argc, _TCHAR* argv[])
{
int b[sizeof(X)];
proc1(b);
return 0;
}
1> ----构建已启动:项目:cpptest,配置:发布Win32
------1>cpptest.cpp 1>cpptest.cpp(14):错误C2664:“proc1”:无法将参数1从“int[48]”转换为“void*[]”1>指向的类型是不相关的;转换需要重新解释转换, C样式转换或功能样式转换 ======生成:0成功,1失败,0最新,0跳过==========
因此sizeof(struct X)是48。这也适用于C代码。这是我使用的代码片段:
template <typename T>
void get_sizeof() {
switch (*((int*)0x1234)) { case sizeof(T): case sizeof(T):; }
}
这个宏基于grep的答案。定义宏,如下所示:
#define COMPILE_TIME_SIZEOF(t) template<int s> struct SIZEOF_ ## t ## _IS; \
struct foo { \
int a,b; \
}; \
SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;
您将得到如下类似的输出:
error: 'SIZEOF_long_IS<4> SIZEOF_long_IS' redeclared as different kind of symbol
SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;
错误:“SIZEOF_long_是SIZEOF_long_是”重新声明为不同类型的符号
SIZEOF##t##u是SIZEOF#t#u;
这仍然是一个解决方法,但很容易使用。我开发了一个名为编译时打印机的工具,用于在编译过程中输出值和类型 您可以在以下位置在线试用: 可在以下位置找到存储库: 要将任何类型的大小作为输出,请执行以下操作:
constexpr auto unused = ctp::print(sizeof(YourType));
@elcuco-第二行应该是
sizeof(*b)
@R塞缪尔:或者只是sizeof*b
sizeof
是一个不需要括号的操作符,除了类型名必须用括号括起来,类似于强制转换语法。我什么时候可以=jsizeof
在编译时计算,已知的只是参数的类型——在这两种情况下都是bar
。如果您有一个更大的bar
子类,并且您将指向该子类实例的指针传递到此函数中,您仍然只得到bar
的大小-多态性在这个级别上不起作用。这是一个很好的观点。您需要在派生类中使用一个虚拟方法来返回它们自己的大小。旁白:看到sizeof
被用作“函数”是我非常恼火的事情。这不是一个函数;是接线员。如果声明int i
,则sizeof i
和sizeof(int)
都应产生相同的结果。(我特意在sizeof
后面加了一个空格,所以没有人认为它是函数,就像我在if
,之后做的那样,,而或者是。sizeof
是一个操作符,而不是一个函数。您不能获取sizeof
的地址(而可以获取函数的地址):-当然,我应该说,这只适用于Visual C++,因为原问题没有指定平台。我现在只在Windows上工作,因此我有偏见。我想知道哪个版本的编译器支持这个开关。当然-sizeof(C),其中C是类。打印是你的问题,这就是我要找的!谢谢如果不希望出现错误,而只希望出现警告,请将其用作完整类型的模板参数,然后定义该类型的未使用对象。即Wow未使用的警告代码>。对于VS2010,不要忘了查看“输出”窗口,因为“错误列表”只包含一条不显示大小值的压缩消息。也不要被VS2010的IntelliSense愚弄,它可以报告cl显示的不同数字。注意:我必须定义一个局部变量来观察gcc4.6上的任何有用消息。换句话说,我在成员变量方面运气不佳,但这并不能完全回答这个问题。我得到了一个不同的错误代码,其中编译器(avrgcc)没有用它的值替换sizeof()表达式。解决方法是编写一次sizeof(dummy),然后提供其他情况(如1、2、4、8等)。这适用于简单类型,但使用更复杂的东西(如结构或类)实现会很痛苦
error: duplicate case value '8'
switch (*((int*)0x1234)) { case sizeof(T): case sizeof(T):; }
^
#define COMPILE_TIME_SIZEOF(t) template<int s> struct SIZEOF_ ## t ## _IS; \
struct foo { \
int a,b; \
}; \
SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;
COMPILE_TIME_SIZEOF(long);
error: 'SIZEOF_long_IS<4> SIZEOF_long_IS' redeclared as different kind of symbol
SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;
constexpr auto unused = ctp::print(sizeof(YourType));