2

I've seen this in C/C++ code:

char * GetName()
{
  return "Aurian";
}

What is exactly going on here under the hood? Where in memory is "Aurian" stored such that it survives when I leave the GetName() scope, AND I get a char * to it? I'm guessing it doesn't follow the same rules as say, returning an int. And how does this relate to

char * name = "Aurian";

Is this implementation dependant? Also, would GetName() just be compiled away to just "Aurian"?

This thread seems to suggest that some sort of jump table might be used for all string literals, for GCC anyway.

Frank
  • 335
  • 2
  • 10
  • 1
    You should have gotten [a warning](http://coliru.stacked-crooked.com/a/ca4f165a8ce323d5) about that `const char*` -> `char*` conversion. – Borgleader Jul 01 '17 at 02:39
  • 1
    In practice string literals go (usually) in a read-only memory segment reserved for literals, so the function is returning a pointer to the string in that segment. Other literals too big to be immediate operands - double precision floating point constants for example - will be in the same segment. Your description of what an optimizer might do is a little vague. If the function were auto-in-lined, the function call that returns the pointer to the literal would be replaced by a simple use of the pointer itself. – Gene Jul 01 '17 at 02:44
  • 1
    The same place as every other string literal (i.e. static storage area) – M.M Jul 01 '17 at 02:44
  • 1
    Yes, where your string will live in memory is implementation dependent. – sigjuice Jul 01 '17 at 02:58
  • Gene, M.M - thanks, this answers my question. From Wikipedia, it looks like string literals might be stored in the .Data segment, along with other globals and statics that have pre-defined values. – Frank Jul 01 '17 at 03:31
  • For an elf, it will probably end up in `.rodata`, the loader will hopefully copy it to a page w/o the write-bit set. – Brian Cain Jul 01 '17 at 03:34
  • 1
    Answers differ between C and C++. Recommend to tag this post with only one of those language. – chux - Reinstate Monica Jul 01 '17 at 03:57

2 Answers2

1

It looks like the string constants are stored in the read only part of data segment (along with other non-zero initialized static variables). Check the assembly!

I compile this

#include<stdio.h>
  char * GetName()
  {
     return "Aurian";
  }
  int main()
  {
      printf("%s", GetName());
      return 0;
  }

and the assembly looks like

    .section    .rodata
    .LC0:
      .string "Aurian"
      .text
      .globl  GetName
      .type   GetName, @function
  GetName:
  .LFB0:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      movl    $.LC0, %eax
      popq    %rbp
      .cfi_def_cfa 7, 8
      ret
      .cfi_endproc
  .LFE0:
      .size   GetName, .-GetName
      .section    .rodata
  .LC1:
      .string "%s"
      .text
      .globl  main
      .type   main, @function
  main:
  .LFB1:
      .cfi_startproc
      pushq   %rbp
      .cfi_def_cfa_offset 16
      .cfi_offset 6, -16
      movq    %rsp, %rbp
      .cfi_def_cfa_register 6
      movl    $0, %eax
      call    GetName
      movq    %rax, %rsi
      movl    $.LC1, %edi
      movl    $0, %eax
      call    printf
      movl    $0, %eax
      popq    %rbp
      .cfi_def_cfa 7, 8
      ret
      .cfi_endproc
physicist
  • 844
  • 1
  • 12
  • 24
  • Ok, so I don't really know assembly, but it looks like in the read-only data segment (.rodata) there is an address (.LC0) in which the string "Aurian" is stored. Then, in the GetName function, it looks like we copy LC0 to eax, which I'm guessing is a register that stores the return value of GetName. Is that basically it? – Frank Jul 01 '17 at 05:38
  • all these .Lxx: are labels. Check this post https://stackoverflow.com/questions/5325326/what-is-the-meaning-of-each-line-of-the-assembly-output-of-a-c-hello-world .LC local constant .LFB function beginning, .LFE function ending, And yes the address of string constant is being put to the accumulator (eax) register and which is then sent as an argument for the printf call. Here is the picture for layout of a program https://en.wikipedia.org/wiki/File:Program_memory_layout.pdf – physicist Jul 01 '17 at 05:49
-1

It is used as the Exit code for the function, so it's storage location is operating system dependent. The C language don't specify these low level details. They vary from platform to platform.

In UNIX flavored systems, this value will be the return value of the wait() or waitpid() system call. Until these functions are called, the return code is stored in the PID entry in the linux kernel.

As we know

  • global variables ,static variables ,Dynamic variables have Heap storage

  • pointers and parameters of the function have Stack storage

  • constant variables are stored in the code itself(data segments)

so based on these types these variables are stored in stack until they are returned from the stack frame

In your case the function finds space on stack after stack calls stack frame to return implicitly

when they are returned, they are stored in the CPU registers ..it is possible that we may consume two or more CPU registers which is OS dependent

shashank
  • 11
  • 7
  • While I don't think anything you say is really incorrect, you seem to have misunderstood the question. It's just about where the characters are stored after the function returns a pointer to them. Nothing to do with the return value of a process or thread. – Harun Jul 01 '17 at 03:49