Like Tree2Likes

argv in the global main function and array or pointers to pointers

This is a discussion on argv in the global main function and array or pointers to pointers within the C++ Programming forums, part of the General Programming Boards category; Since this discussion about the parameters of main() seems to be a bit off topic, perhaps it should be moved ...

  1. #16
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,246
    Since this discussion about the parameters of main() seems to be a bit off topic, perhaps it should be moved into it's own thread?
    O_o

    You've already asked that. Please don't ask it again.

    If a moderator agrees, it will be moved.

    [Edit]
    They are not genies, paid, or omnipresent; they are casual contributes just like you. (*)
    [/Edit]

    It's not me that you need to convince, it's the authors of text books and articles such as this one. Did you read this article?
    No. It is very definitely you that is confused. Sure, the authors may also be confused, but they aren't here.

    You'll note that I actually don't care about the reference to the types of the parameters of the`main' function. The suggestion of `argv' as an actual array is an easy mistake to make, and the idea of the suggestion, when forwarded by others such likely as those you keep quoting, is to simplify consumption of a new concept; I have no problem with it.

    This is seems to be an issue of semantics.
    I would have agreed until post #22. The code example you gave in post #22 tells me that you don't understand the non-existent relationship between variables in different scopes which coincidentally have the same name. The code in post #22 also tells me that you don't appreciate the way arrays are passed to functions as pointers--thus "decaying into a pointer"--to the first element of the array. These two things are my concern. I could not care less about `main' or what other people have to say about `main'.

    When you posted: "This can't be determined by it's usage as a parameter in a function call or prototype. Only the actual instance of the declaration of x would determine if it's an array such as" the discussion stopped being about semantics if that's how it started.

    The two variables, the `x' in the function parameter and `x' stack variable, are two different variables; you can, and should, reason about those different variables in isolation because they have no bearing on each other. The `x' in the function parameter is always a pointer regardless of the `x' stack variable type.

    Let me give you another example by way of situation:

    This code exists in a library:

    Code:
    void foo1(int x[], int c){int cc;for(cc = 0; cc < c; ++cc){printf("%d", x[cc]);}}
    void foo2(int y[], int c){int cc;for(cc = 0; cc < c; ++cc){printf("%d", y[cc]);}}
    I have this header:

    Code:
    void foo1(int x[], int c);
    void foo2(int y[], int c);
    This code exists in my client base:

    Code:
    int main()
    {
    int z1;
    int z2[256];
    int * z3 = &z1;
    foo1(z2, 256);
    foo2(z3, 1);
    }
    Salem, a moderator, happens to be in mood so he drops by repository and changes the header:

    Code:
    void foo1(int * x);
    void foo2(int * y);
    The type of `x' has not changed.
    The type of `y' has not changed.
    The type of `z1' has not changed.
    The type of `z2' has not changed.
    The type of `z3' has not changed.
    The functionality of `foo1' has not changed.
    The functionality of `foo2' has not changed.

    Do you understand?

    Soma

    (*) Except for Salem who is clearly some kind of sexy robot alien thing.
    Last edited by phantomotap; 05-22-2013 at 04:39 PM.

  2. #17
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    Quote Originally Posted by rcgldr View Post
    This is seems to be an issue of semantics.
    Quote Originally Posted by phantomotap View Post
    I would have agreed until post #22. The code example you gave in post #22 tells me that you don't understand the non-existent relationship between variables in different scopes
    I understand about scope. In the case of post #22, the prototype for foo() is used to define how a function should call foo(), and to confirm that the actual instance of foo() complies with the prototype for foo(). I was considering the scope of x within the function calling foo() as opposed to the scope of x within foo() itself. This is what I meant by an issue of semantics.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,717
    Quote Originally Posted by rcgldr
    Since this discussion about the parameters of main() seems to be a bit off topic, perhaps it should be moved into it's own thread?
    Good point, and done. Unfortunately, this means that references to post numbers here are now off.

    Quote Originally Posted by rcgldr
    It's not me that you need to convince, it's the authors of text books and articles such as this one.
    Well, I think that in practice, although the terminology used is wrong, unless they are denying that argv is a pointer to a pointer, there usually is no problem since the beginner is likely to use argc rather than say, try and use sizeof(argv). I don't have any qualms talking about argv as if it were an array either when it is easily understood that I am using loose terminology for simplification rather than denying that argv is a pointer to a pointer. Consider also that even the standard uses loose or colloquial terminology, e.g., referring to a "pointer to a string" when it means "pointer to the first character of a string". Likewise, I don't see a problem with saying "pointer to an array" when I mean "pointer to the first element of an array", unless there is potential for confusion, e.g., the reader might not understand the difference and that I actually meant the latter.

    As such, from a pedagogical perspective, it is probably okay for an introductory book to refer to argv as an array of pointers to char. Later, the distinction between an array of pointers and a pointer to a pointer can be threshed out. Nonetheless, it is not okay for an author to claim that argv is not a pointer to a pointer when it is declared with a particular syntax.

    Quote Originally Posted by rcgldr
    Wiki's standard is that some citable reference should be given for any claim. Once again, I have yet to read any text book or article that specifically states that argv in main is not an array of pointers (as opposed to it can alternately declared as a pointer to pointer).
    We can write a textbook entry or article for you if you really want

    Quote Originally Posted by rcgldr
    I understand about scope. In the case of post #22, the prototype for foo() is used to define how a function should call foo(), and to confirm that the actual instance of foo() complies with the prototype for foo(). I was considering the scope of x within the function calling foo() as opposed to the scope of x within foo() itself. This is what I meant by an issue of semantics.
    If x is a parameter of foo, then it does not exist in the scope of the function that calls foo (unless it is a recursive call, but then the x would be from a different stack frame). Therefore, there is nothing to consider.

    This is why I talk about formal parameter versus actual argument. argv is the formal parameter. You can loosely talk about it as if it were the actual argument, but that does not change the fact that it is the formal parameter, whose type is char** regardless of which syntax you use for the definition of main. In fact, consider:
    Code:
    void foo(int x[]);
    
    int main()
    {
        int numbers[256];
        int* p = numbers;
        foo(p);
    }
    
    // ...
    In this case, the actual argument of foo as called in main is not an array: it is a pointer.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,246
    We can write a textbook entry or article for you if you really want
    O_o

    That is dangerous road to travel.

    I'm positive we could find self-proclaimed expert programmers on "Youtube" documenting how `main' always returns `void'.

    I'd rather stick to the discussion in terms of what it is instead of adding to the problem by even pretending that the existence of such articles implies authoritative knowledge.

    In this case, the actual argument of foo as called in main is not an array: it is a pointer.
    o_o

    Now you are just trying to show off by posting an example I didn't think of posting.

    Soma

  5. #20
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    In "The C Programming Language", by Kernighan & Ritchie, copyright 1978, section 5.11 Command Line Arugments, the book states ... (argv) is a pointer to to an array of character strings, and then uses this syntax for main():

    Code:
    main(argc, argv)
    int argc;
    char *argv[];
    {
    ...
    }
    This would seem to be the original definition for argv.

    The real issue here is that pointer syntax can be used for arrays, and array syntax can be used for pointers, and that arrays passed to functions are passed by reference (as pointers) while most variable types are passed by value. The examples shown in "The C Programming Language" include:

    Code:
    int a[10];
    int *pa = a;
    
        *(a+i);
        pa[i];
    The book states that In evaluating a[ i ], C converts it to *(a + i) ...

    The fact that arrays are passed by reference can lead to unexpected results for new programmers:

    Code:
    #include<stdio.h>
    
    int a[10];
    
    void foo(int x[10]);
    
    int main(int argc, char *argv[])
    {
        printf("sizeof a = %d\n", sizeof(a));
        foo(a);
        return(0);
    }
    
    void foo(int x[10])
    {
        printf("sizeof x = %d\n", sizeof(x));
    }
    Which results in this output:

    sizeof a = 40
    sizeof x = 4

  6. #21
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,246
    The real issue here is that pointer syntax can be used for arrays, and array syntax can be used for pointers, and that arrays passed to functions are passed by reference (as pointers) while most variable types are passed by value.
    *derp*

    Well, that looks you've got us stumped.

    Oh, wait, no, never mind, that is completely wrong. o_O

    You can't use pointer syntax for arrays.

    Code:
    void Go(int f[]); // The `f' variable is a pointer. Always.
    Code:
    void Go(int * f); // The `f' variable is a pointer. Always.
    Code:
    {
    int s[1]; // The `s' variable is an array; it can only and will DECAY into a pointer.
    }

    Code:
    {
    int * s; // The `s' variable is a pointer. Always.
    }
    The fact that arrays are passed by reference can lead to unexpected results for new programmers:
    You aren't going to like this at all.

    In the C family, arrays aren't passed by reference by default as you imply. They are passed, for like the fifteenth time, as a pointer to the first element of the array.

    [Edit]
    Just to be clear, pointers are also passed by value by default; pointers are not passed by reference. The value of a pointer is just an address. You are, by passing the address to a pointer, providing a reference to the relevant variable.
    [/Edit]

    However, you can force the array to be passed as a reference.

    [Edit]
    This is C++. You can do this in ISO C, but for life of me I can't recall how exactly to force the array, instead of the pointer to the first element, to carry.
    [/Edit]

    Code:
    #include<stdio.h>
     
    int a[10];
     
    void foo(int (&x)[10]);
     
    int main(int argc, char *argv[])
    {
        printf("sizeof a = %d\n", sizeof(a));
        foo(a);
        return(0);
    }
     
    void foo(int (&x)[10])
    {
        printf("sizeof x = %d\n", sizeof(x));
    }
    Soma
    Last edited by phantomotap; 05-22-2013 at 10:51 PM.

  7. #22
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,587
    rcgldr, this is C++, and not C. Furthermore, the C++14 standard disagrees with you:

    Quote Originally Posted by C++14 Standard, 3.6.1
    An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both
    — a function of () returning int and
    — a function of (int, pointer to pointer to char) returning int
    as the type of main (8.3.5). In the latter form, for purposes of exposition, the first function parameter is called argc and the second function parameter is called argv, where argc shall be the number of arguments passed to the program from the environment in which the program is run. If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (ntmbs s) (17.5.2.1.4.2)
    This implies that the function shall take an int and a pointer to pointer to char. Not an array. Yes, it mentions that argv essentially has to point to an array, but it does not mean that it is an array.
    Elkvis likes this.
    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. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,717
    Quote Originally Posted by rcgldr
    In "The C Programming Language", by Kernighan & Ritchie, copyright 1978, section 5.11 Command Line Arugments, the book states ... (argv) is a pointer to to an array of character strings, and then uses this syntax for main():

    Code:
    main(argc, argv)
    int argc;
    char *argv[];
    {
    ...
    }
    This would seem to be the original definition for argv.
    You are confusing explanatory text with a precise and accurate statement of what is the type of the parameter.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #24
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    Quote Originally Posted by phantomotap View Post
    In the C family, arrays aren't passed by reference ...
    From "The C Programming Language", section 4.3 More on Function Arguments: The effect is that arrays are passed by reference.

    Quote Originally Posted by Elysia View Post
    rcgldr, this is C++, and not C. Furthermore, the C++14 standard disagrees with you: This implies that the function shall take an int and a pointer to pointer to char. Not an array. Yes, it mentions that argv essentially has to point to an array, but it does not mean that it is an array.
    The standard uses the syntax argv[0], argv[argc-1], not *(argv) and *(argv + argc-1), so this is a bit confusing. Then again, that ancient K&R book states that argv[argc-1] will be converted to *(argv + argc-1) .

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,717
    Quote Originally Posted by rcgldr
    From "The C Programming Language", section 4.3 More on Function Arguments: The effect is that arrays are passed by reference.
    And that is still correct to this day: the effect is that arrays are passed by reference, at least where their contents are concerned. However, that does not mean that arrays are passed by reference, unless you specially make it so in C++.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #26
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    Quote Originally Posted by laserlight View Post
    And that is still correct to this day: the effect is that arrays are passed by reference, at least where their contents are concerned. However, that does not mean that arrays are passed by reference, unless you specially make it so in C++.
    I'm not sure what you mean that it does not mean arrays are passed by reference unless you specially make it so in C++. It seems the code below is doing what I would expect it to do (example program and output, the addresses are the same):

    Code:
    #include <iostream>
    
    using namespace std;
    
    int a[10];
    
    void foo(int x[10]);
    
    int main(int argc, char *argv[])
    {
        cout << "sizeof a = " << sizeof(a) << endl;
        cout << "addrof a = " << a << endl;
        foo(a);
        return(0);
    }
    
    void foo(int x[10])
    {
        cout << "sizeof x = " << sizeof(x) << endl;
        cout << "addrof x = " << x << endl;
    }
    output:

    sizeof a = 40
    addrof a = 00403378
    sizeof x = 4
    addrof x = 00403378

  12. #27
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,717
    Quote Originally Posted by rcgldr
    I'm not sure what you mean that it does not mean arrays are passed by reference unless you specially make it so in C++.
    phantomotap gave an example of passing an array by reference earlier (post #31). Notice that sizeof on the parameter is that of the array, not a pointer.

    Quote Originally Posted by rcgldr
    It seems the code below is doing what I would expect it to do (example program and output, the addresses are the same):
    The array is converted to a pointer to its first element. Therefore, this demonstrates the passing of a pointer by value, not the passing of an array by reference. However, in effect, you are passing the array by reference since the pointer is a reference, in the computer science sense.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #28
    ZuK
    ZuK is offline
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    
    using namespace std;
    
    int main( int argc, char * argv[] ) {
        char arr[][5] = { "kurt", "was", "here", "x" };
        cout << "the array:" << endl;
        for( int idx = 0; idx < 3; ++idx ) {
    	    cout << "  " << (void*)arr[idx] << " " << setw(5) << left 
                 << arr[idx] << " " << (int)( arr[idx+1]-arr[idx]) << endl;		
        }
    
        cout << "the arguments:" << endl;
        for( int idx = 1; idx < argc-1; ++idx ) {
    	    cout << "  " << (void*)argv[idx] << " " << setw(5) << left << argv[idx] 
                 << " " << (int)( argv[idx+1]-argv[idx]) << endl;		
        }
    }
    my OUTPUT
    Code:
    # ./a.out kurt was here x
    the array:
      0xbfd776bc kurt  5
      0xbfd776c1 was   5
      0xbfd776c6 here  5
    the arguments:
      0xbfd7896f kurt  5
      0xbfd78974 was   4
      0xbfd78978 here  5
    So what does that tell me
    The elements that argv points to cannot be arrays because their sizes are different. argv must be a pointer to a pointer.
    Kurt

  14. #29
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    Quote Originally Posted by laserlight View Post
    phantomotap gave an example of passing an array by reference earlier (post #21). The array is converted to a pointer to its first element. Therefore, this demonstrates the passing of a pointer by value, not the passing of an array by reference. However, in effect, you are passing the array by reference since the pointer is a reference, in the computer science sense.
    OK, I was getting confused by the general computer science terminology of passing by reference as opposed to the C++ terminology of passing by reference.

    If I use "void foo(int (&x)[10])", then within foo, sizeof(x) is the size of the array, and x, &x, and &x[0], all point to the first element of the array.

    If I use "void foo(int x[10])", then within foo(), sizeof(x) is the size of a pointer, and x and &x[0] point to the first element of the array, but &x points to a location in memory that contains a pointer to the first element of the array.

    Getting back to the point of this thread, C++ standard states that argv is to be declared as char **argv, but then continues stating argv[0], argv[1], ... are pointers to the initial characters of strings, using argv as an array of pointers, so it's confusing. The issue is that the syntax in C / C++ for using arrays or pointers is interchangeable.
    Last edited by rcgldr; 05-23-2013 at 03:26 AM.

  15. #30
    Registered User
    Join Date
    Apr 2013
    Posts
    1,283
    Quote Originally Posted by ZuK View Post
    The elements that argv points to cannot be arrays because their sizes are different. argv must be a pointer to a pointer.
    The alternate definition for argv is that it is an array of pointers to the initial characters of strings, not to an array of elements (of fixed size). Also I don't think there is a requirement for how the strings that argv points to are arranged in memory, so argv[i+1] - argv[i], would not have to result in 1+strlen(argv[i]), although it probably does in most cases.
    Last edited by rcgldr; 05-23-2013 at 03:27 AM.

Page 2 of 3 FirstFirst 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array of pointers and pointer for arrays with argv
    By thames in forum C Programming
    Replies: 4
    Last Post: 12-02-2012, 09:24 AM
  2. Global Access to Global Class without so many pointers
    By parad0x13 in forum C++ Programming
    Replies: 1
    Last Post: 11-11-2009, 01:48 PM
  3. Replies: 4
    Last Post: 07-01-2009, 01:53 PM
  4. Array of function pointers
    By Yasir_Malik in forum C Programming
    Replies: 5
    Last Post: 11-20-2003, 07:41 PM
  5. Array of function pointers?
    By The V. in forum C++ Programming
    Replies: 3
    Last Post: 10-16-2001, 08:37 PM

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