简体   繁体   English

sizeof如何知道操作数数组的大小?

[英]How does sizeof know the size of the operand array?

This may be a stupid question but how does the sizeof operator know the size of an array operand when you don't pass in the amount of elements in the array. 这可能是一个愚蠢的问题,但是当你没有传入数组中的元素数量时,sizeof运算符如何知道数组操作数的大小。 I know it doesn't return the total elements in the array but the size in bytes, but to get that it still has to know when the array ends. 我知道它不会返回数组中的总元素,而是以字节为单位返回大小,但为了得到它,它仍然必须知道数组何时结束。 Just curious as to how this works. 只是好奇这是如何工作的。

sizeof is interpreted at compile time, and the compiler knows how the array was declared (and thus how much space it takes up). sizeof在编译时解释,编译器知道数组是如何声明的(因此它占用了多少空间)。 Calling sizeof on a dynamically-allocated array will likely not do what you want, because (as you mention) the end point of the array is not specified. 在动态分配的数组上调用sizeof可能无法执行您想要的操作,因为(如您所述)未指定数组的结束点。

The problem underlying your trouble to understand this might be because you are confusing arrays and pointers, as so many do. 你理解这个问题的根本问题可能是因为你混淆了数组和指针,正如许多人所做的那样。 However, arrays are not pointers . 但是, 数组不是指针 A double da[10] is an array of ten double , not a double* , and that's certainly known to the compiler when you ask it evaluate sizeof(da) . double da[10]是十个double的数组,而不是double* ,当你要求它评估sizeof(da)时,编译器当然知道它。 You wouldn't be surprised that the compiler knows sizeof(double) ? 你不会对编译器知道sizeof(double)感到惊讶吗?

The problem with arrays is that they decay to pointers to their first elements automatically in many contexts (like when they are passed to functions). 数组的问题在于它们在许多上下文中自动衰减指向它们的第一个元素(比如它们传递给函数时)。 But still, array are arrays and pointers are pointers. 但仍然,数组是数组,指针是指针。

Except in one case, sizeof does it's thing at compile time. 除了一个案例, sizeof在编译时就是这样。 At compile time, the compiler keeps track of the full type of an object [Edit: well, everything it knows about the type of the object, anyway -- if the type isn't complete so that doesn't include the size, attempting to use sizeof will fail], and sizeof basically just "exports" one piece of that information from the compiler into the code being compiled, so it becomes essentially a constant in the resulting code. 在编译时,编译器会跟踪对象的完整类型[编辑:嗯,它知道关于对象类型的所有内容 - 无论如何 - 如果类型不完整,那么不包括大小,尝试使用sizeof将失败], sizeof基本上只是将一条信息从编译器“导出”到正在编译的代码中,因此它在结果代码中基本上是一个常量。

The exception is when sizeof is applied to variable length array (VLA) 1 . 例外情况是将sizeof应用于可变长度数组(VLA) 1 When applied to a VLA, sizeof evaluates its operand (which it doesn't otherwise), and produces the actual size of the VLA. 当应用于VLA时, sizeof评估其操作数(否则不会),并生成VLA的实际大小。 In this case, the result is not a constant. 在这种情况下,结果不是常数。


1. VLAs officially became a part of C in C99, but some compilers supported them before that. 1.在V99中,VLA正式成为C的一部分,但在此之前,一些编译器支持它们。 Although not officially part of C++, some compilers (eg, g++) include VLAs as an extension to C++ as well. 虽然不是C ++的正式部分,但是一些编译器(例如,g ++)也包括VLA作为C ++的扩展。

编译器知道应用程序中每种类型的大小,而sizeof只是请求编译器为您生成该值。

Sizeof is a compile time operator; Sizeof是一个编译Sizeof算符; it has as much information as the compiler does. 它拥有与编译器一样多的信息。 (And obviously the compiler does know the size of the array). (显然编译器确实知道数组的大小)。

This is why if you call sizeof on a pointer you get the width of the pointer, not the size of the array to which that pointer points. 这就是为什么如果在指针上调用sizeof ,则获得指针的宽度,而不是指针所指向的数组的大小。

Sizeof can only be applied to completely defined types. Sizeof只能应用于完全定义的类型。 The compiler will either be able to determine the size at compile time (eg, if you had a declaration like int foo[8];), or it will be able to determine that it has to add code to track the size of a variable-length array (eg, if you had a declaration like int foo[n+3];). 编译器要么能够在编译时确定大小(例如,如果你有一个类似int foo [8]的声明;),或者它将能够确定它必须添加代码来跟踪变量的大小-length数组(例如,如果你有一个类似int foo [n + 3]的声明;)。

Contrary to other answers here, note that as of C99, sizeof() is not necessarily determined at compile time, since arrays may be variable-length. 相反,这里其他的答案,请注意,作为C99的,sizeof()会不一定在编译时决定,因为阵列可以是可变长度。

If you're using sizeof on a local variable, it knows how many elements you declared. 如果您在局部变量上使用sizeof ,它会知道您声明了多少个元素。 If you're using sizeof on a function parameter, it doesn't know; 如果你在函数参数上使用sizeof ,它就不知道; it treats the parameter as a pointer to the array and sizeof gives the size of a pointer. 它将参数视为指向数组的指针, sizeof指定指针的大小。

Quote from wiki : 来自wiki的引用:

It is the responsibility of the compiler's author to implement the sizeof operator in a way specific and correct for a given implementation of the language. 编译器作者有责任以特定的方式实现sizeof运算符,并且对于给定的语言实现是正确的。 The sizeof operator must take into account the implementation of the underlying memory allocation scheme to obtain the sizes of various datatypes. sizeof运算符必须考虑底层内存分配方案的实现,以获取各种数据类型的大小。 sizeof is usually a compile-time operator, which means that during compilation, sizeof and its operand get replaced by the result-value. sizeof通常是编译时运算符,这意味着在编译期间,sizeof及其操作数将被结果值替换。 This is evident in the assembly language code produced by a C or C++ compiler. 这在C或C ++编译器生成的汇编语言代码中很明显。 For this reason, sizeof qualifies as an operator, even though its use sometimes looks like a function call. 出于这个原因,sizeof有资格作为运算符,即使它的使用有时看起来像函数调用。

The sizeof operator 'knows' the size of all atomic datatypes, since structs, unions and arrays can only be constructed by assembling the atomic types it's easy to determine the size of array of any type. sizeof运算符 '知道'所有原子数据类型的大小,因为结构,联合和数组只能通过组装原子类型来构造,因此很容易确定任何类型的数组的大小。 It uses basic arithmetic to determine complex types (during compile time). 它使用基本算法来确定复杂类型(在编译期间)。

sizeof is usually evaluated at compile time. sizeof 通常在编译时进行评估。 The notable exception is C99's variable length arrays. 值得注意的例外是C99的可变长度数组。

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        int count = atoi(argv[1]);
        int someArray[count];

        printf("The size is %zu bytes\n", sizeof someArray);
    }
    else puts("No");
}

sizeof is calculated at compile-time. sizeof在编译时计算。 This is why when you create a dynamic array you create it the following way. 这就是为什么在创建动态数组时,可以通过以下方式创建它。

char * array;
int size;
//Get size somehow.
array = malloc(size*(sizeof(char)));

// now during the compile the compiler knows for sure the size of char. //现在在编译期间,编译器肯定知道char的大小。 since it has to align them on the memory. 因为它必须将它们对准内存。 At this point it the OS knows how much size it has to allocate. 此时,OS知道它必须分配多少大小。

Variable length arrays on the other hand are created on the Stack . 另一方面, 可变长度数组堆栈上创建。 But any malloc allocated memory would be created on the heap. 但是任何malloc分配的内存都将在堆上创建。

Sizeof is always evaluated at compile time. 始终在编译时评估Sizeof。 In multi pass compiler while generating the symbol table compiler must determine the size of each symbol declared to proceed further to generate intermediate code. 在多传递编译器生成符号表时,编译器必须确定声明的每个符号的大小,以进一步生成中间代码。 So for all sizeof referrences in the code replaces the exact value. 因此,代码中的所有sizeof引用都会替换确切的值。 At intermediate code generation stage all the operators,statements are converted to right intermediate code (ASM/other format). 在中间代码生成阶段,所有运算符,语句都转换为正确的中间代码(ASM /其他格式)。 Finally, m/c code generation stage it converts it to the machine code. 最后,m / c代码生成阶段将其转换为机器代码。

Some discussions seen above wrt the dynamic allocations relating to sizeof is not in the context at all. 上面讨论的一些讨论与sizeof相关的动态分配根本不在上下文中。 Any reference to size(*p) where p is a pointer of any data type , compiler just finds out the data type of *p and replaces its size , not go to check the MCB header of the allocated block to see what is the allocated memory size. 任何对size(* p)的引用,其中p是任何数据类型的指针,编译器只找到* p的数据类型并替换它的大小,而不是检查分配块的MCB头以查看分配的内容内存大小。 It is not at run time. 它不是在运行时。 For example double *p; 例如double * p; sizeof(*p) can still be done without allocating any memory for pointer p. sizeof(* p)仍然可以在不为指针p分配任何内存的情况下完成。 How is it possible? 这怎么可能?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM