是否有标准化的方法来获取 C++ 中的类型大小(以字节为单位)?编译器?

发布于 2024-09-24 20:11:28 字数 851 浏览 3 评论 0原文

我想知道是否有某种标准化方法可以在预处理器阶段获取内存中的类型大小 - 因此在宏形式中, sizeof() 不会削减它。

如果它们不是标准化方法,那么大多数 IDE 都使用它们的传统方法吗?

任何人都可以想到其他方法来获取此类数据吗?

我想我可以做两阶段构建之类的事情,获取测试程序的输出并将其反馈到 IDE 中,但这并不比我自己#defining 它们更容易。

想法?

编辑:

我只是希望能够与 交换代码

#ifdef / #endif

我是否天真地认为 IDE 或底层编译器可能会在某些宏下定义该信息?当然,预处理器不会获取任何实际机器代码生成函数的信息,但 IDE 和编译器会获取,并且它们会调用预处理器并提前向其声明内容。

进一步编辑

我想象的一个可以想象的概念是这样的:

C++委员会有一个标准,规定对于每种类型(也许只有C++原生的类型),编译器必须向IDE提供一个头文件,默认情况下包括声明大小的头文件在本机类型使用的内存中,如下所示:

#define CHAR_SIZE 8
#define INT_SIZE 32
#define SHORT_INT_SIZE 16
#define FLOAT_SIZE 32
// etc

此过程中的某个地方是否存在缺陷?

进一步编辑

为了解决多平台构建阶段问题,也许这个标准可以要求像 lacqui 所示的简单程序需要编译并运行默认情况下运行,这样,无论输入什么类型大小将与在第二个或“正常”构建阶段编译代码的机器相同。

抱歉:

我一直使用“变量”而不是“类型”

I was wondering if there is some standardized way of getting type sizes in memory at the pre-processor stage - so in macro form, sizeof() does not cut it.

If their isn't a standardized method are their conventional methods that most IDE's use anyway?

Are there any other methods that anyone can think of to get such data?

I suppose I could do a two stage build kind of thing, get the output of a test program and feed it back into the IDE, but that's not really any easier than #defining them in myself.

Thoughts?

EDIT:

I just want to be able to swap code around with

#ifdef / #endif

Was it naive of me to think that an IDE or underlying compiler might define that information under some macro? Sure the pre-processor doesn't get information on any actual machine code generation functions, but the IDE and the Compiler do, and they call the pre-processor and declare stuff to it in advance.

EDIT FURTHER

What I imagined as a conceivable concept was this:

The C++ Committee has a standard that says for every type (perhaps only those native to C++) the compiler has to give to the IDE a header file, included by default that declares the size in memory that ever native type uses, like so:

#define CHAR_SIZE 8
#define INT_SIZE 32
#define SHORT_INT_SIZE 16
#define FLOAT_SIZE 32
// etc

Is there a flaw in this process somewhere?

EDIT EVEN FURTHER

In order to get across the multi-platform build stage problem, perhaps this standard could mandate that a simple program like the one shown by lacqui would be required to compile and run be run by default, this way, whatever that gets type sizes will be the same machine that compiles the code in the second or 'normal' build stage.

Apologies:

I've been using 'Variable' instead of 'Type'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

听不够的曲调 2024-10-01 20:11:29

抱歉,此信息在预处理器阶段不可用。要计算变量的大小,您必须完成几乎所有解析和抽象评估工作 - 不是完全代码生成,但您必须能够评估常量表达式并替换模板参数,例如。而且您必须比预处理器通常更了解代码生成目标。

我认为,两阶段构建是大多数人在实践中所做的事情。有些 IDE 将整个编译器作为库内置到其中,这使它们可以更有效地完成工作。

Sorry, this information isn't available at the preprocessor stage. To compute the size of a variable you have to do just about all the work of parsing and abstract evaluation - not quite code generation, but you have to be able to evaluate constant-expressions and substitute template parameters, for instance. And you have to know considerably more about the code generation target than the preprocessor usually does.

The two-stage build thing is what most people do in practice, I think. Some IDEs have an entire compiler built into them as a library, which lets them do things more efficiently.

桃气十足 2024-10-01 20:11:29

为什么你还需要这个?

cstdint include 提供 typedef#defines 描述所有标准整数类型,包括精确宽度 int 类型的 typedef#defines 获取它们的完整值范围。

Why do you need this anyway?

The cstdint include provides typedefs and #defines that describe all of the standard integer types, including typedefs for exact-width int types and #defines for the full value range for them.

你列表最软的妹 2024-10-01 20:11:29

不,这是不可能的。举例来说,完全可以在一台机器上运行预处理器,并在另一台完全不同的机器上完全独立地进行编译,(至少某些)类型的大小(可能)不同。

举一个具体的例子,考虑 SQLite 的正态分布就是他们所说的“合并” - - 您在计算机上实际编译的单个已预处理的源代码文件。

No, it's not possible. Just for example, it's entirely possible to run the preprocessor on one machine, and do the compilation entirely separately on a completely different machine with (potentially) different sizes for (at least some) types.

For a concrete example, consider that the normal distribution of SQLite is what they call an "amalgamation" -- a single already-preprocessed source code file that you actually compile on your computer.

债姬 2024-10-01 20:11:29

您想根据某种类型的大小生成不同的代码吗?也许你可以通过模板专业化来做到这一点:

#include <iostream>

template <int Tsize>
struct dosomething{
  void doit() { std::cout << "generic version" << std::endl; }
};

template <>
void dosomething<sizeof(int)>::doit()
{ std::cout << "int version" << std::endl; }

template <>
void dosomething<sizeof(char)>::doit()
{ std::cout << "char version" << std::endl; }


int main(int argc, char** argv)
{
  typedef int foo;
  dosomething<sizeof(foo)> myfoo;
  myfoo.doit();

}

You want to generate different code based on the sizes of some type? maybe you can do this with template specializations:

#include <iostream>

template <int Tsize>
struct dosomething{
  void doit() { std::cout << "generic version" << std::endl; }
};

template <>
void dosomething<sizeof(int)>::doit()
{ std::cout << "int version" << std::endl; }

template <>
void dosomething<sizeof(char)>::doit()
{ std::cout << "char version" << std::endl; }


int main(int argc, char** argv)
{
  typedef int foo;
  dosomething<sizeof(foo)> myfoo;
  myfoo.doit();

}
夜灵血窟げ 2024-10-01 20:11:29

那会如何运作呢?在预处理阶段,大小是未知的。那时,您只有源代码。查找类型大小的唯一方法是编译其定义。

您不妨寻求一种方法来获取编译阶段运行程序的结果。答案是“你不能,你必须运行程序才能得到它的输出”。就像您需要编译程序才能获得编译器的输出一样。

你想做什么?

关于您的编辑,它似乎仍然很困惑。

可以想象,这样的标头可能存在于内置类型中,但绝不会存在于变量中。也许可以编写一个宏来用硬编码的数字替换已知的类型名称,但如果您给它一个变量名称,它就不知道要做什么。

再一次,你想做什么?您想要解决的问题是什么?如果您向我们提供更多背景信息,可能会有一个明智的解决方案。

How would that work? The size isn't known at the preprocessing stage. At that point, you only have the source code. The only way to find the size of a type is to compile its definition.

You might as well ask for a way to get the result of running a program at the compilation stage. The answer is "you can't, you have to run the program to get its output". Just like you need to compile the program in order to get the output from the compiler.

What are you trying to do?

Regarding your edit, it still seems confused.

Such a header could conceivably exist for built-in types, but never for variables. A macro could perhaps be written to replace known type names with a hardcoded number, but it wouldn't know what to do if you gave it a variable name.

Once again, what are you trying to do? What is the problem you're trying to solve? There may be a sane solution to it if you give us a bit more context.

猫瑾少女 2024-10-01 20:11:29

对于常见的构建环境,许多框架都手动进行设置。例如,

http: //www.aoc.nrao.edu/php/tjuerges/ALMA/ACE-5.5.2/html/ace/Basic__Types_8h-source.html

定义诸如 ACE_SIZEOF_CHAR 之类的内容。我买的一本名为 POSH 的书中描述的另一个库也以一种非常包容的方式做到了这一点:http://www. hookatooka.com/wpc/

For common build environments, many frameworks have this set up manually. For instance,

http://www.aoc.nrao.edu/php/tjuerges/ALMA/ACE-5.5.2/html/ace/Basic__Types_8h-source.html

defines things like ACE_SIZEOF_CHAR. Another library described in a book I bought called POSH does this too, in a very includable way: http://www.hookatooka.com/wpc/

北方的韩爷 2024-10-01 20:11:29

“标准化”一词就是问题所在。没有标准的方法来做到这一点,但使用某种配置实用程序设置一些预处理器符号并不是很困难。一个真正简单的方法是编译并运行一个小程序,该程序使用 sizeof 检查大小,然后输出带有一些符号集的包含文件。

The term "standardized" is the problem. There's not standard way of doing it, but it's not very difficult to set some pre-processor symbols using a configuration utility of some sort. A real simple one would be compile and run a small program that checks sizes with sizeof and then outputs an include file with some symbols set.

请止步禁区 2024-10-01 20:11:28

根据您的构建环境,您也许能够编写一个实用程序来生成其他文件包含的标头:

int main(void) {
    out = make_header_file();  // defined by you
    fprintf(out, "#ifndef VARTYPES_H\n#define VARTYPES_H\n");

    size_t intsize = sizeof(int);
    if (intsize == 4)
        fprintf(out, "#define INTSIZE_32\n");
    else if (intsize == 8)
        fprintf(out, "#define INTSIZE_64\n");
    // .....
    else fprintf(out, "$define INTSIZE_UNKNOWN\n");
}

当然,请根据需要对其进行编辑。然后在需要这些定义的地方包含“vartypes.h”。

编辑:或者:

fprintf(out, "#define INTSIZE_%d\n", (sizeof(int) / 8));
fprintf(out, "#define INTSIZE %d\n", (sizeof(int) / 8));

注意第二个中缺少下划线 - 第一个创建可在#ifdef中使用的INTSIZE_32。第二个创建可以使用的 INTSIZE,例如 char 位[INTSIZE];

警告:这仅适用于 8 位字符。大多数现代家用和服务器计算机都将遵循这种模式;但是,某些计算机可能使用不同大小的 char

Depending on your build environment, you may be able to write a utility program that generates a header that is included by other files:

int main(void) {
    out = make_header_file();  // defined by you
    fprintf(out, "#ifndef VARTYPES_H\n#define VARTYPES_H\n");

    size_t intsize = sizeof(int);
    if (intsize == 4)
        fprintf(out, "#define INTSIZE_32\n");
    else if (intsize == 8)
        fprintf(out, "#define INTSIZE_64\n");
    // .....
    else fprintf(out, "$define INTSIZE_UNKNOWN\n");
}

Of course, edit it as appropriate. Then include "vartypes.h" everywhere you need these definitions.

EDIT: Alternatively:

fprintf(out, "#define INTSIZE_%d\n", (sizeof(int) / 8));
fprintf(out, "#define INTSIZE %d\n", (sizeof(int) / 8));

Note the lack of underscore in the second one - the first creates INTSIZE_32 which can be used in #ifdef. The second creates INTSIZE, which can be used, for example char bits[INTSIZE];

WARNING: This will only work with an 8-bit char. Most modern home and server computers will follow this pattern; however, some computers may use different sizes of char

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文