Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以打印出C+的大小+;在编译时初始化? 在编译时可以判断C++类的大小吗?< /P>_C++ - Fatal编程技术网

是否可以打印出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
是一个不需要括号的操作符,除了类型名必须用括号括起来,类似于强制转换语法。我什么时候可以=j
sizeof
在编译时计算,已知的只是参数的类型——在这两种情况下都是
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));