Observe how the value 195 corresponds to the ret
(return from function) instruction on 8086 compatibles. This definition of main
thus behaves as if you defined it as int main() {}
when executed.
On some platforms, const
data is loaded into an executable but not writeable memory region whereas mutable data (i.e. data not qualified const
) is loaded into a writeable but not executable memory region. For this reason, the program “works” when you declare main
as const
but not when you leave off the const
qualifier.
Traditionally, binaries contained three segments:
- The
text
segment is (if supported by the architecture) write-protected and executable, and contains executable code, variables of static storage duration qualified const
, and string literals
- The
data
segment is writeable and cannot be executed. It contains variables not qualified const
with static storage duration and (at runtime) objects with allocated storage duration
- The
bss
segment is similar to the data
segment but is initialized to all zeroes. It contains variables of static storage duration not qualified const
that have been declared without an initializer
- The
stack
segment is not present in the binary and contains variables with automatic storage duration
Removing the const
qualifier from the variable main
causes it to be moved from the text
to the data
segment, which isn't executable, causing the segmentation violation you observe.
Modern platforms often have further segments (e.g. a rodata
segment for data that is neither writeable nor executable) so please don't take this as an accurate description of your platform without consulting platform-specific documentation.
Please understand that not making main
a function is usually incorrect, although technically a platform could allow main
to be declared as a variable, cf. ISO 9899:2011 §5.1.2.2.1 ¶1, emphasis mine:
1 The function called at program startup is named main
. The implementation declares no prototype for this function. It shall be defined with a return type of int
and with no parameters (...) or with two parameters (...) or equivalent; or in some other implementation-defined manner.
ret
(return from function) on 8086 and its successors. You can guess what happens when you put that in a variable and call that variable as a function. – Pileupret
instruction? – Homeopathic