Thread: Variable declarations before main function parentheses?

  1. #1
    Registered User
    Join Date
    Apr 2022
    Posts
    1

    Variable declarations before main function parentheses?

    Variable declarations before main function parentheses?-screenshot-2022-04-25-114156-png

    Is this valid code? What exactly is it doing?

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    992
    The following first two examples are effectively equal. The both define the code to allow for Command Line Arguments:
    Code:
    // K&R function definition
    // Legal but out-dated
    
    int main(argc, argv)
        int argc;
        char **argv;
    {
        // ...
        
        return 0;
    }
    
    // Modern function definition, Recommended
    
    int main(int argc, char **argv)
    {
        // ...
        
        return 0;
    }
    
    // Command Line Arguments not allowed
    int main(void)
    {
        // ...
    
        return 0;
    }

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,312
    > Is this valid code?
    Yeah, maybe, if you travel back to the 1970's.
    It was rendered obsolete towards the end of the 1980's when the language got standardised.

    Whether you can find a modern compiler that accepts archaic C is another matter.

    It's the very old way of doing
    Code:
    int main ( int argc, char **argv )
    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.

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,422
    In the olden days, not only did the return type of a function default to int, but the variables did, too. So this would be a correct program:
    Code:
    f(a, b) { return a + b; } 
    main() { return f(1, 2); }
    A long time ago being crazy meant something. - Charles Manson

  5. #5
    Registered User
    Join Date
    Apr 2022
    Posts
    8
    Hey John, good tip there. I hadn't realized that the parameters also defaulted to int. I'm going to have to try that in Power C for the C64. Thanks!

  6. #6
    Registered User
    Join Date
    Apr 2022
    Posts
    8
    Quote Originally Posted by erg0xy View Post
    Variable declarations before main function parentheses?-screenshot-2022-04-25-114156-png

    Is this valid code? What exactly is it doing?
    Ok here's whats happening. When you declare main with parameters, you are permitting the operating system to pass the command line used to invoke the program TO the program. This is how command line parameters are sent to programs. Here is an example of a program taking command line parameters

    xcopy a:*.* /s

    xcopy is the program and a:*.* is a parameter as is /s. Both seperated by spaces.

    if we write a program like this:

    Code:
    #include<stdio.h>
    
    main(argc, argv)
    int argc;
    char **argv;
    {
        int c = 0;
    
       while(c++ < argc)
            printf("%s ", argv[c]);
    
        putchar('\0);
    
        return 0;
    }
    We could expect an output of:

    xcopy a:*.* /s


    Each parameter is a string, so here is the break down:

    argv[0] = "xcopy"
    argv[1] = "a:*.*"
    argv[2] = "/s"

    Hope this helps.

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,422
    Quote Originally Posted by bigsig View Post
    Hey John, good tip there.
    It's not a "tip". It's a historical fact. Programs should never be written that way since 1990.

    Also, your example program is wrong since the a:*.* would be replaced by the shell with the matching filenames before the program is called. Although obviously the OP's question wasn't about what argc and argv are for, but the "strange" way they are defined in his example code.
    A long time ago being crazy meant something. - Charles Manson

  8. #8
    Registered User
    Join Date
    Apr 2022
    Posts
    8
    Oh I'm sorry, John. I didn't intend to offend you with tip.

  9. #9
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    875
    Quote Originally Posted by john.c View Post
    Also, your example program is wrong since the a:*.* would be replaced by the shell with the matching filenames before the program is called.
    Not so with MS-DOS. Programs received the wildcard pattern as-is. That's the only way that commands like xcopy a:*.* /s could even work--the shell (CMD) passes a:*.* to the xcopy program, and the program handles the pattern internally.

  10. #10
    Registered User
    Join Date
    Apr 2022
    Posts
    8
    Yes, Chris that is correct! I've written a couple of parsing functions to handle wildcards as parameters for both the Commodore 64 as well as DOS fairly recently. John must have thought I meant something else. However he is probably quite right that it was not the answer the OP was looking for, but I wasn't sure so I figured it couldn't hurt.

  11. #11
    Registered User
    Join Date
    Dec 2017
    Posts
    1,422
    So you were assuming the OP was using MS-DOS?
    A long time ago being crazy meant something. - Charles Manson

  12. #12
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    875
    Quote Originally Posted by john.c View Post
    So you were assuming the OP was using MS-DOS?
    It still applies to CMD running on the latest versions of Windows.

    Microsoft is (in)famous for maintaining backwards compatibility with even things that many people consider to be misfeatures or bugs (e.g., having reserved, special file names in every single directory. Try creating a file called "con.txt" or "aux.bmp" on Windows. You can't because MS still wants to support a hack they added to MS-DOS to work around a limitation of some software from around 40 years ago).

  13. #13
    Registered User
    Join Date
    Dec 2017
    Posts
    1,422
    So on Windows if the current directory contains x1.txt, x2.txt, and x3.txt and the following program is run like ./a.out x*.txt, the output would be ./a.out and x*.txt? And I would need to implement my own wildcard handling to make it work properly (or maybe there's a Windows function to help)? That's a bit of a portability problem.
    Code:
    #include <stdio.h>
     
    int main(int argc, char **argv) {
        for (int i = 0; i < argc; ++i) printf("%s\n", argv[i]);
        return 0;
    }
    A long time ago being crazy meant something. - Charles Manson

  14. #14
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    992
    Quote Originally Posted by bigsig View Post
    John must have thought I meant something else. However he is probably quite right that it was not the answer the OP was looking for, but I wasn't sure so I figured it couldn't hurt.
    The OP was unfamiliar with the structure of a K&R style function definition, not about the details about command line arguments. The question was answered.

    Let's stay on topic of the original question, and move on.

  15. #15
    Registered User
    Join Date
    Dec 2017
    Posts
    1,422
    So I tried the program from my last post on a Windows machine and the output was:
    Code:
    C:\Users\Me\CodeBlocksProjects\CommandLine\bin\Debug>CommandLine x*.txt
    CommandLine
    x1.txt
    x2.txt
    x3.txt
    A long time ago being crazy meant something. - Charles Manson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 04-15-2020, 12:49 AM
  2. Replies: 2
    Last Post: 03-25-2016, 05:34 AM
  3. Replies: 8
    Last Post: 01-31-2014, 03:52 AM
  4. Passing variable from an outside function to main?
    By ZeroDivision in forum C Programming
    Replies: 6
    Last Post: 11-08-2013, 08:32 PM
  5. Passing variable from function - main - function
    By ulti-killer in forum C Programming
    Replies: 2
    Last Post: 11-01-2012, 12:14 PM

Tags for this Thread