Where the C++ literal-constant storage in memory?

旧时模样 提交于 2019-12-23 03:47:18

问题


Where the C++ literal-constant storage in memory? stack or heap?

int *p = &2

is wrong. I want know why? Thanks

-------------------------------------------------

My question is "Where the C++ literal-constant storage in memory", "int *p = &2

is wrong",not my question.


回答1:


The details depend on the machine, but assuming a commonest sort of machine and operating system... every executable file contains several "segments" - CODE, BSS, DATA and some others.

CODE holds all the executable opcodes. Actually, it's often named TEXT because somehow that made sense to people way back decades ago. Normally it's read-only.

BSS is uninitialized data - it actually doesn't need to exist in the executable file, but is allocated by the operating system's loader when the program is starting to run.

DATA holds the literal constants - the int8, int16, int32 etc along with floats, string literals, and whatever weird things the compiler and linker care to produce. This is what you're asking about. However, it holds only constants defined for use as variables, as in

const long x = 2;

but unlikely to hold literal constants used in your source code but not tightly associated with a variable. Just a lone '2' is dealt with directly by the compiler. For example in C,

print("%d", 2);

would cause the compiler to build a subroutine call to print(), writing opcodes to push a pointer to the string literal "%d" and the value 2, both as 64-bit integers on a 64-bit machine (you're not one of those laggards still using 32-bit hardware, are you? :) followed by the opcode to jump to a subroutine at (identifier for 'print' subroutine).

The "%d" literal goes into DATA. The 2 doesn't; it's built into the opcode that stuffs integers onto the stack. That might actually be a "load register RAX immediate" followed by the value 2, followed by a "push register RAX", or maybe a single opcode can do the job. So in the final executable file, the 2 will be found in the CODE (aka TEXT) segment.

It typically isn't possible to make a pointer to that value, or to any opcode. It just doesn't make sense in terms of what high level languages like C do (and C is "high level" when you're talking about opcodes and segments.) "&2" can only be an error.

Now, it's not entirely impossible to have a pointer to opcodes. Whenever you define a function in C, or an object method, constructor or destructor in C++, the name of the function can be thought of as a pointer to the first opcode of the machine code compiled from that function. For example, print() without the parentheses is a pointer to a function. Maybe if your example code were in a function and you guess the right offset, pointer arithmetic could be used to point to that "immediate" value 2 nestled among the opcodes, but this is not going to be easy for any contemporary CPU, and certainly isn't for beginners.




回答2:


Let me quote relevant clauses of C++03 Standard. 5.3.1/2

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue.

An integer literal is an rvalue (however, I haven't found a direct quote in C++03 Standard, but C++11 mentiones that as a side note in 3.10/1). Therefore, it's not possible to take an address of an integer literal.

What about the exact place where 2 is stored, it depends on usage. It might be a part of an machine instruction, or it might be optimized away, e.g. j=i*2 might become j=i+i. You should not rely upon it.




回答3:


You have two questions:

Where are literal constants stored? With the exception of string literals (which are actual objects), pretty much wherever the implementation wants. It will usually depend on what you're doing with them, but on a lot of architectures, integral constants (and often some special floating point constants, like 0.0) will end up as part of a machine instruction. When this isn't possible, they'll usually be placed in the same logical segment as the code.

As to why taking the address of an rvalue is illegal, the main reason is because the standard says so. Historically, it's forbidden because such constants often never exist as a separate object in memory, and thus have no address. Today... one could imagine other solutions: compilers are smart enough to put them in memory if you took their address, and not otherwise; and rvalues of class type do have a memory address. The rules are somewhat arbitrary (and would be, regardless of what they were)—hopefully, any rules which would allow taking the address of a literal would make its type int const*, and not int*.



来源:https://stackoverflow.com/questions/11965402/where-the-c-literal-constant-storage-in-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!