C itself has no concept of segments (nor far pointers), this will be a feature of the underlying implementation or architecture (which you haven't specified). Segmented architectures and near/far/tiny pointers are ancient things from the 8086 days - most code nowadays (with the possible exception of embedded stuff) gives you a flat memory model where you don't have to worry about that.
All the standard states is that the actual characters of the string will be characters that you are not allowed to modify.
For what it's worth (which isn't much). my implementation stores the string itself in memory marked read-only (this may or may not be a code segment, you can easily have other segments marked read-only) and p
(the address of the first of those characters) is placed on the stack at runtime.
If you run your compiler to produce the assembler output:
gcc -S qq.c
you'll see something like (in qq.s
in my case):
.file "qq.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "mystring\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
call __alloca
call ___main
movl $LC0, -4(%ebp)
movl $0, %eax
leave
ret
You can see from that, it's in its own section rdata
(read-only data), not in the text
section.
A possible disadvantage of placing it into text
would be that things like DEP (data execute protection) would be much harder.
You want both code and read-only data to be read-only, but you also want code to be executable - you don't generally want read-only data to be executable.