Newbie question

This is a discussion on Newbie question within the C Programming forums, part of the General Programming Boards category; Hi, Just started programming about 2 weeks ago, I have a basic understanding of it, just wanted to know if ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    2

    Newbie question

    Hi,
    Just started programming about 2 weeks ago, I have a basic understanding of it, just wanted to know if you could help me spot the problem with this program, it compiles, it just doesnt do what I want it to do.

    Code:
    #include<stdio.h>
    
    void main()
    
    {
    	int choice = 0;
    	int num1 = 0;
    	int num2 = 0;
    	int sum = 0;
    	int num3 = 0;
    	int num4 = 0;
    	int answer = 0;
    
        printf("Please Choose a option\n");
    	printf("For Addition mode please press 1\n");
    	printf("For Muliplication mode please press 2\n");
    	scanf("Choose = %i", choice);
    
    	if(choice == 1)
    	{
    		printf("Please enter a number");
    		scanf("Number1 = %i", num1);
            printf("Please enter a second number");
    		scanf("Number2 = %i", num2);
    
    		sum = num1 + num2;
    
    		printf("The sum of Number1 and Number2 is %d", sum);
    	}
    	if(choice == 2)
    	{
    		printf("Please enter a number");
    		scanf("Number1 = %i", num3);
            printf("Please enter a number");
    		scanf("Number2 = %i", num4);
    
    		answer = num3 * num4;
    
    		printf("The answer of Number1 times Number2 is %d", answer);
    
    	}
    
    	printf("Thank you");
    
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    For questions like this, it helps if you describe "it doesn't do what I want it to do" in terms of "what it does and how that is different from what you want it to do" - that saves us from trying to figure out what it actually does, and how that is different from what you expect. [I mean, it could be that you want a set of numbers printed as a neat column, but I find a case where you MAY, under some circumstances cause a divide by zero].

    Code:
    	scanf("Choose = %i", choice);
    Do you actually expect the user to type in
    Code:
    Choose = 1
    You also should pass a pointer to the variable that you are reading with scanf().

    You may want to try:
    Code:
    	scanf("%d", &choice);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,497
    > void main()
    main returns int, see the FAQ

    > scanf("Choose = &#37;i", choice);
    1. You forgot the &, as in &choice
    2. Do you expect the user to type in "Choose = 1" or just "1" ?
    In a scanf control string, each letter matches itself unless it's a conversion.
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    2
    Thanks for the help people - aaarrgghh those small mistakes always trouble me, Elysia could you just explain to me what is wrong with the void main().

  5. #5
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,546
    It's not standard. Link to FAQ is in signature.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What's not really explained in the FAQ is that the "void main()" construction is broken BECAUSE although you define the content of main, it is called by the startup code that sets up the entire C environment, and it also "finishes off" the C environment. In the finishing off process, it will set the "exit value" for the process - this is the return value from main(). If you use "void main()", the C environment will still think that main returns something, and take whatever "garbage" is where the return value should have been. This means that the exit value from your applicaiton is "undefined". Not only that, it may change if you recompile the program with some different compiler settings, change the code inside main [or some of the code called by main, depending on where the place that the return value from main is last used].

    Having things "undefined" means that "anything could happen".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,546
    I think the FAQ needs to be updated a little, hm?
    I think I'll quote your reply instead, matsp, since it's a much better explanation
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    I think the FAQ needs to be updated a little, hm?
    Well, it's obviously a balance between having a FAQ that tells you what you NEED TO KNOW and one that is "precise and detailed".

    I'm just showing off

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,546
    It does say that it should follow a description discussing why it's bad, but the FAQ somehow prematurely ends there... Hmmm.
    Still, I like the explanation, so I linked to it in case anyone asks
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    Quote Originally Posted by matsp View Post
    What's not really explained in the FAQ is that the "void main()" construction is broken BECAUSE although you define the content of main, it is called by the startup code that sets up the entire C environment, and it also "finishes off" the C environment. In the finishing off process, it will set the "exit value" for the process - this is the return value from main(). If you use "void main()", the C environment will still think that main returns something, and take whatever "garbage" is where the return value should have been. This means that the exit value from your applicaiton is "undefined". Not only that, it may change if you recompile the program with some different compiler settings, change the code inside main [or some of the code called by main, depending on where the place that the return value from main is last used].
    That's an interesting explanation; unfortunately, it's totally incorrect.

    void main() is "broken" because it is not guaranteed to be supported by all compilers.

    If a compiler supports void main(), then - in practice - the compiler (or it's associated libraries) usually support some rational behaviour if a programmer chooses to use it, rather than just returning some undefined value to the operating system.

  11. #11
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,546
    Let's investigate, shall we?
    EDIT: I believe grumpy is right. If I use void main, then the compiler will do xor eax, eax before returning to the pre-main code and thus the return will be 0.
    /me quotes new post.
    Last edited by Elysia; 12-06-2007 at 03:30 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by grumpy View Post
    That's an interesting explanation; unfortunately, it's totally incorrect.

    void main() is "broken" because it is not guaranteed to be supported by all compilers.

    If a compiler supports void main(), then - in practice - the compiler (or it's associated libraries) usually support some rational behaviour if a programmer chooses to use it, rather than just returning some undefined value to the operating system.
    I think we're actually saying the same thing, but in different ways.

    If we take this (broken) C code:
    Code:
    // foo.c
    void foo(int x)
    {
      // ... code here ... 
    }
    
    // main.c
    extern int foo(int x);
    
    int main() 
    {
        printf("foo returns %d\n", foo(11));
    }
    This will do the same thing as the call to main with a void return type - the return value is completely undefined (and thus will contain "any garbage").

    Of course, in C++ this won't even work, since the name mangling says that int foo(int) is a different function than void foo(int).

    But I beleive that even in a C++ compiler, "main" is implicitly made
    Code:
    extern "C" int main(/*whatever */);
    . So the return type is still not involved in the name of the function.

    Of course, there are further complications: The call to main may be different for a void main than it is for a int main in some architectures [e.g. one where the return value from a function is passed on the stack], and this could potentially cause problems in those architectures. Just like EBCDIC, I have not experienced an architectuer yet that has this behaviour, but it's entirely concievable to have such an architecture.


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Let's investigate, shall we?
    EDIT: I believe grumpy is right. If I use void main, then the compiler will do xor eax, eax before returning to the pre-main code and thus the return will be 0.
    /me quotes new post.
    If you use C++ or C99, this may be because "main without return is defined to return 0". What compiler was this with?

    [Or it may simply be that the compiler "fixes" a common behaviour?]

    gcc doesn't do this:
    Code:
    D:\temp>echo void main() {} > foo.c
    
    D:\temp>gcc -S foo.c
    foo.c: In function `main':
    foo.c:1: warning: return type of 'main' is not `int'
    
    D:\temp>more foo.s
            .file   "foo.c"
            .def    ___main;        .scl    2;      .type   32;     .endef
            .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, -4(%ebp)
            movl    -4(%ebp), %eax
            call    __alloca
            call    ___main
            leave
            ret
    [Unless you RELY on ___main setting eax to zero - which I don't believe is at all guaranteed].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,546
    Visual Studio 2008 (Team Edition), compiled as C.
    Or perhaps we might say that the behavior is undefined, since different compilers may do different things:

    Code:
    00401944  xor         eax,eax 
    00401946  mov         esp,ebp 
    00401948  pop         ebp  
    00401949  ret
    Asm code at end of void main.

    Code:
    00401944  mov         eax,46h 
    }
    00401949  mov         esp,ebp 
    0040194B  pop         ebp  
    0040194C  ret
    Asm code at end of int main, returning 70.

    Code:
    00401152  push        dword ptr [envp (40319Ch)] 
    00401158  push        dword ptr [argv (4031A0h)] 
    0040115E  push        dword ptr [argc (403198h)] 
    00401164  call        main (401800h) 
    00401169  add         esp,0Ch 
    0040116C  mov         dword ptr [mainret (4031B0h)],eax 
    Asm code calling main.
    Last edited by Elysia; 12-06-2007 at 04:15 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,211
    Here's an in depth post I wrote about the subject of void main(), specifically considering the x86 processor. I believe I tested the programs listed with MinGW, so your mileage may vary with them. They are only to be used as proof-of-concept programs that may or may not work for you (since two of the three are technically undefined).

    [C Video Tutorial Collection]

    Of note, I should probably update the programs used and write a new version.

    Similarly, here's another post of mine on the same subject with the same system requirements. Same issues with regard to portability and being potentially undefined:

    No return value

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stupid Newbie question
    By TimL in forum C++ Programming
    Replies: 4
    Last Post: 07-22-2008, 04:43 AM
  2. C prog newbie question
    By Draginzuzu in forum C Programming
    Replies: 1
    Last Post: 02-03-2003, 05:45 PM
  3. a stupid question from a newbie
    By newcomer in forum C++ Programming
    Replies: 4
    Last Post: 01-11-2003, 03:38 PM
  4. confusion with integers (newbie question)
    By imortal in forum C Programming
    Replies: 7
    Last Post: 12-06-2002, 03:09 PM
  5. newbie class templates question
    By daysleeper in forum C++ Programming
    Replies: 2
    Last Post: 09-18-2001, 09:50 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21