LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-12-2010, 10:03 AM   #1
hppyhjh
LQ Newbie
 
Registered: Jul 2010
Posts: 9

Rep: Reputation: 0
why char *argv[] declaration is ok in main arg, but not in body?


char *ar_char_ptr[];

I declare the var in main body, when compile, give the error:
error: array size missing in ‘ar_int_ptr’
so I have to change to char **ar_char_ptr

but the same format declaration is used in main's second argument, char *argv[], and with no error. although the array size is known by the first argument argv.
why?
 
Old 09-12-2010, 03:43 PM   #2
14moose
Member
 
Registered: May 2010
Posts: 83

Rep: Reputation: Disabled
Hi -

The difference is between declaring " *argv[]" as a parameter in a function, and actually defining some variable e.g. "*myarray[]".

This example might help:
Code:
#include <stdio.h>

#define NELMS(A) (sizeof(A) / sizeof(A[0]))

/*
 * Here, I'm defining and declaring "animals" all at the same time.
 * The compiler knows exactly how much storage to allocate; everything works.
 */
char *animals[] = {
  "cow",
  "pig",
  "horse"
};

int
main (int argc,  char *argv[])
{
  for (int i=0; i < (int)NELMS(animals); i++)
    printf ("animals[%d]: %s...\n", i, animals[i]);
  return 0;
}
Quote:
g++ -o x -Wall -pedantic x.cpp

./x
animals[0]: cow...
animals[1]: pig...
animals[2]: horse...
Here's a different example, which DOESN'T work:

Code:
#include <stdio.h>

#define NELMS(A) (sizeof(A) / sizeof(A[0]))

char *animals[];

int
main (int argc,  char *argv[])
{
  for (int i=0; i < (int)NELMS(animals); i++)
    printf ("animals[%d]: %s...\n", i, animals[i]);
  return 0;
}
Quote:
g++ -o x -Wall -pedantic x.cpp

x.cpp:5: error: storage size of "animals" isn't known
This link might also help:
Declaration vs. Definition

Last edited by 14moose; 09-12-2010 at 03:55 PM.
 
1 members found this post helpful.
Old 09-12-2010, 04:23 PM   #3
ArthurSittler
Member
 
Registered: Jul 2008
Distribution: Slackware
Posts: 124

Rep: Reputation: 31
Your declaration is trying to allocate space in your main() routine (probably in the stack frame) for an array of pointers. The compiler needs to know how many pointers are in that array so it can allocate the right amount of space. The compiler writes exit code for every function which pops the local variables from the stack and then pops the return address to the program counter. When your main() exits, it must pop the correct amount of space from the stack because the same stack also holds return addresses from functions. If the wrong number of bytes are popped, then the stack pointer will not be pointing to the return address when it tries to load the program counter with the return address from the stack.

On the other hand, the parameter that main() receives is an array of stack pointers that has been pushed onto the stack by the runtime environment before entering main(). The runtime environment can know how many pointers it pushed onto the stack. Therefore, it knows how many bytes to pop so that its return address is at the top of the stack.

Thus, a calling program can use a variable size of parameters when it calls a subroutine, but a subroutine cannot declare a variable sized array within the subroutine.

Actually, you can make variable sized arrays at run time by allocating memory for them after you know how many items you need in the array. You would call malloc() or some relative of malloc() to allocate the space. You would need some pointer to the base of the array, or course. That pointer would then be a pointer to an array of objects, which, in C is a pointer to a pointer to that type of object.

There is, however, a difference between an array of pointers and a pointer to a pointer. An array of k pointers uses k times as much space as a pointer. A pointer to an array or a pointer to a pointer uses only enough space for a single pointer.

You may also pass a variable number of arguments to a function, just as the runtime environment passes your main() function a variable number of arguments. This functionality is provided by the variable argument list library, which you can access by using
Code:
#include <stdarg.h>
to include the header for the library in your code.

Please let me know if this explanation is helpful.
 
1 members found this post helpful.
Old 09-12-2010, 05:44 PM   #4
14moose
Member
 
Registered: May 2010
Posts: 83

Rep: Reputation: Disabled
hppyhjh -

Everything ArthurSittler is true (as far as I can tell - I didn't bother to read the whole thing )

But I understand your original question as this:
Quote:
Q: Why doesn't "char *arg[]" syntax work when I define a variabe, even though it works fine as a parameter in "main()"?

A: The issue is "declaration" vs. "definition".
I hope my code snippet, and/or the link I gave, answers the question.
 
Old 09-13-2010, 12:56 AM   #5
hppyhjh
LQ Newbie
 
Registered: Jul 2010
Posts: 9

Original Poster
Rep: Reputation: 0
14moose's example is clear and simple
ArthurSittler's explanation is more thorough, i think
thank u both!
 
Old 09-13-2010, 08:36 PM   #6
wroom
Member
 
Registered: Dec 2009
Location: Sweden
Posts: 159

Rep: Reputation: 31
Hm. This is one of the peculiarities in C.
Logically, declaring an array of unknown size containing pointers of some kind...
Code:
char *a[];
...is the same as allocating a pointer to a pointer, like:
Code:
char **a;
Except for the char** not telling the compiler anything much of how you will use the pointer-pointer, other than for accessing some chars with two level pointer indirection.

No other storage is allocated than for one pointer. Except if one declares the variable statically with an initializer, like the following:
Quote:
Originally Posted by 14moose
Code:
char *animals[] = {
  "cow",
  "pig",
  "horse"
};
In this case the compiler knows the size, and allocates an array of pointers, along with the char* initialized content and sets the pointers in the array to point out the "cow", "pig" and "horse" strings.

Lets say we declare:
Code:
char *a[15];
Have we defined an array of 15 char pointers or have we declared a pointer to an array of 15 chars?

(there is one correct answer, but putting out the question shows the ambiguity between how pointers vs arrays work).

If one wants to allocate a pointer to an array of char pointers, without initializing it, then one should declare:
Code:
char **a;
Thus clearly stating to the compiler not to initialize any char strings, nor any array of pointers to them, but just allocating a pointer for it.

If one declares an array of pointers without telling how big the array is, either with a specified nubmer of rows or implicit with an initializer filling in the contents, then the compiler don't know how to allocate the array of pointers.

One could argue that the compiler should treat a "char *a[];" the same as being just a "char **a;", but i suspect that allowing for declaring unbound arrays of pointers will only have the effect that an even bigger number of programs will occationally crash with a segmentation fault.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Hello every body, i'm using redhat linux I don't know about samba server any body seenas Linux - Newbie 2 07-04-2009 03:47 AM
tokenize to put in a char* argv[] list xeon123 Programming 3 10-28-2007 07:22 AM
char * declaration in c; alaios Programming 19 09-14-2005 09:50 PM
Array declaration in class or main function??? redhatrosh Programming 4 03-15-2005 02:13 PM
main(int argc, char **argv) Longinus Programming 4 06-12-2004 07:22 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:35 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration