Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0

    String Literal Scope


    For C90 ( C ) and GCC, how does this work?

    Code:
    char* ptr = NULL; 
    {
    char str[4]={0};
    sprintf(str, "AGH"); 
    
    ptr = str;
    }
    printf("ptr: %s\n", ptr);
    --output--

    ptr: AGH

    ----------

    I understand that if str was a string literal str would be stored in the bss ( essentially as a static ), but sprintf(ing) to a stack allocated buffer, I thought that would be purely stack-based ( and thus the address meaningless after leaving the scope block )?
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,087
    Rep Power
    2222
    Show us the actual code, because what you are showing us there would not do what you are describing.

    HINT: ptr is the address of the ptr function, not a call to the function. ptr() is a function call.

    HINT: the final statement in the function, ptr, would not compile. The address of ptr is a fixed point! You cannot change a fixed point! (if you are at all familiar with The Doctor, then you would know that already) You are trying to change the address of the function to be the address of the string, str. You may not do that!

    And just what are you trying to accomplish with that nonsensical assignment statement anyway? Are you trying to return str from the function? This is C, not Pascal! Use a return statement.

    HINT: What warnings did you get when you tried to compile your program? Did you ignore those warnings? Why did you ignore those warnings? Warnings are far more important than error messages.


    As I said, show us the actual code, a short compilable program that illustrates what you are trying to do. Without that, we can't be certain of what you are trying to do. For that matter, on this forum always post actual code.
    Last edited by dwise1_aol; July 31st, 2013 at 07:21 PM.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0
    Wow you have totally miss-read my question. As per usual the flamer is the one with the egg on their face.



    Originally Posted by dwise1_aol
    Show us the actual code, because what you are showing us there would not do what you are describing.
    It is the actual code buddy, as compiled in VS2008 ( in a main.c ), although GCC compiles / runs the same.

    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
    	char* ptr = NULL; 
    	{
    		char str[4]={0};
    		sprintf(str, "AGH"); 
    
    		ptr = str;
    	}
    	printf("ptr: %s\n", ptr);
    
    	getchar();
    	return 0;
    }
    Also, here is a link: URL=http://codepad.org/RpRcnnAj to an online compiler/interpreter running the above code and displaying the prescribed output, undeniable proof that code will compile and run.



    Originally Posted by dwise1_aol
    HINT: ptr is the address of the ptr function, not a call to the function. ptr() is a function call.
    ptr is not an address to function, it is a pointer to a char array as specified in the declaration.



    Originally Posted by dwise1_aol
    HINT: the final statement in the function, ptr, would not compile. The address of ptr is a fixed point! You cannot change a fixed point! (if you are at all familiar with The Doctor, then you would know that already) You are trying to change the address of the function to be the address of the string, str. You may not do that!
    See above, ptr is not pointing to a function!!! As I have already stated, you have completely miss-interpreted the code.



    Originally Posted by dwise1_aol
    And just what are you trying to accomplish with that nonsensical assignment statement anyway? Are you trying to return str from the function? This is C, not Pascal! Use a return statement.
    I'm trying to fix someone else's code actually, by removing areas of base code which display this outlined behavior. I'm trying to get a handle on why the application is currently stable!



    Originally Posted by dwise1_aol
    HINT: What warnings did you get when you tried to compile your program? Did you ignore those warnings? Why did you ignore those warnings? Warnings are far more important than error messages.
    In VS2008, the default warning level is displaying zero warnings.



    Originally Posted by dwise1_aol
    As I said, show us the actual code, a short compilable program that illustrates what you are trying to do. Without that, we can't be certain of what you are trying to do. For that matter, on this forum always post actual code.
    I did post the actual code you idiot.




    Based on your number of posts, I presume you have some programming knowledge , so I'm going to give you the opportunity to apologize and have a second attempt at interpreting this question ( although a I have a feeling based on your utter arrogance, that you are all bark and no bite, suffering from illusory superiority i.e. the Dunning-Kruger effect URL=http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect ).'
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Location
    India
    Posts
    95
    Rep Power
    4
    str is defined in its scope so u cant use it out side of its scope but memory allocated for it will be freed after function get collapse.
    thats why your output is AGH
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0
    Originally Posted by eramit2010
    str is defined in its scope so u cant use it out side of its scope but memory allocated for it will be freed after function get collapse.
    thats why your output is AGH
    From an different forum ( with seemingly less trolls), I have concluded that generally speaking ( but not always ), C compilers will try to make each function's stack frame a fixed size, rather than expanding and contracting as control flow enters and leaves internal blocks. This is more than likely why the str variable remains intact for the duration of main, and thus is still untouched when the printf occurs.
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    Your code is broken, and it's only pure dumb luck that it works.

    You lose control of the contents of str at the moment you hit the closing brace. Yes, ptr will still point at the same memory location where str used to be, but you've no idea what is stored there. The compiler is free to re-use that memory for some other purpose.

    Here's an example which breaks it.
    Code:
    #include <stdio.h>
    
    int main()
    {
      char* ptr = NULL; 
      {
        char str[4]={0};
        sprintf(str, "AGH"); 
    
        ptr = str;
      }
      {
        char bogo[4] = "NO!";
        printf("%s\n",bogo);
      }
      printf("ptr: %s\n", ptr);
    
      return 0;
    }
    
    
    $ gcc foo.c
    $ ./a.out 
    NO!
    ptr: NO!

    Comments on this post

    • eramit2010 agrees
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Location
    India
    Posts
    95
    Rep Power
    4
    Originally Posted by salem
    Your code is broken, and it's only pure dumb luck that it works.

    You lose control of the contents of str at the moment you hit the closing brace. Yes, ptr will still point at the same memory location where str used to be, but you've no idea what is stored there. The compiler is free to re-use that memory for some other purpose.

    Here's an example which breaks it.
    Code:
    #include <stdio.h>
    
    int main()
    {
      char* ptr = NULL; 
      {
        char str[4]={0};
        sprintf(str, "AGH"); 
    
        ptr = str;
      }
      {
        char bogo[4] = "NO!";
        printf("%s\n",bogo);
      }
      printf("ptr: %s\n", ptr);
    
      return 0;
    }
    
    
    $ gcc foo.c
    $ ./a.out 
    NO!
    ptr: NO!
    but in my code blocks it prints AGH :eek:

    Code:
    #include<stdio.h>
    int main()
    {
      char* ptr = NULL;
      {
        char str[4]={0};
        sprintf(str, "AGH");
    
        ptr = str;
        printf("str=%u",str);
      }
      {
        char bogo[4] = "NO!";
        printf("%s\n",bogo);
        printf("str=%u",bogo);
      }
      printf("ptr: %s\n", ptr);
    
      return 0;
    }

    output:

    Code:
    str=2686728
    NO!
    str=2686724
    ptr: AGH
    and it allocate memory for str and bog at different locations.

    and in online gcc compiler http://www.compileonline.com/compile_c_online.php
    also giving same output as my code blocks.
    Last edited by eramit2010; August 1st, 2013 at 12:53 AM.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0
    Originally Posted by salem
    Your code is broken, and it's only pure dumb luck that it works.

    You lose control of the contents of str at the moment you hit the closing brace. Yes, ptr will still point at the same memory location where str used to be, but you've no idea what is stored there. The compiler is free to re-use that memory for some other purpose.

    Here's an example which breaks it.
    Code:
    #include <stdio.h>
    
    int main()
    {
      char* ptr = NULL; 
      {
        char str[4]={0};
        sprintf(str, "AGH"); 
    
        ptr = str;
      }
      {
        char bogo[4] = "NO!";
        printf("%s\n",bogo);
      }
      printf("ptr: %s\n", ptr);
    
      return 0;
    }
    
    
    $ gcc foo.c
    $ ./a.out 
    NO!
    ptr: NO!
    I think we are all aware of the fact that it is undefined behavior, and would be avoided in practice. The original question was how is the code compiled without overriding the string, which comes down to the how and when the stack frames are collapsed.
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    > but in my code blocks it prints AGH
    That's because the code is broken!

    No two compilers are bound to produce identical results with broken code.

    Your compiler happens to just allocate everything up front as a simple sum of all the local variable sizes.

    My compiler works out a minimal size based on the mutually exclusive lifetimes of variables in non-overlapping scopes.

    Your compiler lures you into a false sense of security by producing the answer you expect, despite the flaws in the program.

    If I comment out the braces, like so
    Code:
    //  {
        char bogo[4] = "NO!";
        printf("%s\n",bogo);
    //  }
    Then I'm back to
    Code:
    $ gcc foo.c
    $ ./a.out 
    NO!
    ptr: AGH
    You can see how fragile the whole idea is.
    The code is 1 edit away from a WTF is happening!?

    Comments on this post

    • eramit2010 agrees : thanks now i understood reason why i got different output.thanks for clearing my concept of local variable's scope...
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,087
    Rep Power
    2222
    Originally Posted by hoffman_jwr
    The original question was how is the code compiled without overriding the string, which comes down to the how and when the stack frames are collapsed.
    Well then rather than waste everybody's time with your broken code and piss-poor attitude, why don't you just simply generate an assembly listing of your program and read it? That will tell you everything you'd want to know about what the program is actually doing, including how and when the stack frames are collapsed.

    Actually knowing is much better than your preferred approach of stumbling around blind and stupid.
  20. #11
  21. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    > The original question was how is the code compiled without overriding the
    > string, which comes down to the how and when the stack frames are collapsed.
    It has already been demonstrated above that the same code produces different answers when compiled with different compilers. This is a classic hallmark of code which has undefined behaviour.

    Rummaging through assembler listing of generated code is only going to tell you about that particular code compiled with that particular compiler. Whilst it's an interesting exercise which might have some utility when it comes to some advanced debugging later on, it won't do anything about fixing the underlying problems in the code (except perhaps to confirm that the foo compiler works as theorised).

    But will knowing all that about a specific compiler help you write better code? I doubt it. All you'll know are the quirks of one particular implementation. It isn't knowledge you can apply generally to help you write better code.

    It's just a variation on the regular theme of "what is i++ + ++i" and a regular parade of students from India (mostly, and some other places) who troop in bearing "TurboC" and claim to know a particular answer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0
    Originally Posted by dwise1_aol
    Well then rather than waste everybody's time with your broken code
    Oh sorry, i didn't realize your response posts on this forum were involuntary. I won't post in the future because I'm just wasting your time.

    Originally Posted by dwise1_aol
    and piss-poor attitude
    lol my piss poor attitude? - don't make me laugh! You're the one who attacked me based on your incorrect understanding of the problem!

    Originally Posted by dwise1_aol
    why don't you just simply generate an assembly listing of your program and read it? That will tell you everything you'd want to know about what the program is actually doing, including how and when the stack frames are collapsed.

    Actually knowing is much better than your preferred approach of stumbling around blind and stupid.
    So basically if one doesn't have a completely thorough understanding of the underlying assembler, then they don't have a right to ask questions about C... yeah that totally makes sense in a C forum. I didn't realize in the context of this forum category, "C Programming" actually equates to "Assembler Programming", my mistake.
  24. #13
  25. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,087
    Rep Power
    2222
    You worthless idiot! Having to steal a minute from my busy work schedule, I misread your code fragment and then asked highly pertinent questions based on the misinterpretation. That was not attack. You attacked me, you dribbling imbecile! Please take a moment to pull your minuscule cranium out of your rectum!

    So basically if one doesn't have a completely thorough understanding of the underlying assembler, then they don't have a right to ask questions about C... yeah that totally makes sense in a C forum. I didn't realize in the context of this forum category, "C Programming" actually equates to "Assembler Programming", my mistake.
    You blithering idiot!

    When the questions have to do with C, then you need to know something about C, but when the questions specifically have to do with assembly, then you need to turn to assembly. Being such a low-grade moron, how do you even manage to tie your shoes in the morning?

    C already told you everything you needed to know about your program: That is undefined behavior. DO NOT DO THAT! But imbecile that you are, you did it anyway, completely ignoring what C told you! Why do you claim that you did it? To find out how the compiler had managed the stack frames. Well, C cannot tell you one single thing about the management of stack frames. What can? Assembly! It certainly doesn't take a genius to realize that, but you're such an idiot that I'm sure you still don't understand. You're just a worthless waste of bandwidth.


    I won't post in the future because I'm just wasting your time.
    Finally! You said something intelligent!

    **** off, you stupid troll!
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    8
    Rep Power
    0
    Originally Posted by dwise1_aol
    **** off, you stupid troll!
    The fact of the matter is, that you have failed to provide any form of constructive feedback, whilst being completely unsympathetic towards a fellow forum user's reasons for asking a question - you have no idea the reasons I needed an answer to this question, nor should you have cared. I fail to see how this is not trolling.

    In stark contrast, a number of other forums were extremely helpful in explaining why the C code I posted behaves the way it does. I now have a much better understanding of how the compiler collapses a stack frame only after exiting a function.

    So in a nutshell, disgraceful behavior like this is why forums like Dev Shed are now becoming increasingly obsolete, and competitor forums are becoming increasingly popular. I will be de-registering my account, and not returning in the future. So as a senior "Contributing User", you have utterly failed as a mentor, and helped push one more person away from Dev Shed. Good Job :thumbs:
  28. #15
  29. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,087
    Rep Power
    2222
    So **** off already! And the next time somebody asks for information that's needed to try to answer your question, don't attack them for it!
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo