blm@spec0.UUCP (Bharat Lal Madhyani) (05/05/89)
/*************/ /* program1.c*/ /*************/ /* consider the following small c_program path : is an array of pointers to characters, which has been initialized p_path : is a pointer to path, i.e it is a pointer to pointer to character The program basically travels the array path and prints the character string associated with the pointer at that time. */ char *path[] = { "/usr/pgmr/blm/citoh/shit", "/usr/pgmr/junk", "/usr/lib/news/history", "/usr/bin/vi", "Testing Initialization", 0 }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program2.c */ /***************/ /* In this program , I have defined a new variable bad_address -- which is a pointer to character. And while initializing the path array of pointers to characters I am getting the following error : "program2.c", line 30: illegal initialization why it is so ? bad_address is also an address(pointer), which also points to character string. And as we all know that two dimensional array are implemented through pointers, i.e char a[10][20] means : a is an array of 10 pointers, and each element of array a is an array of 20 characters. */ char *bad_address = "Testing Initialization"; char *path[] = { "/usr/pgmr/blm/citoh/shit", "/usr/pgmr/junk", "/usr/lib/news/history", "/usr/bin/vi", bad_address, 0 }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program3.c */ /***************/ /* Still consider another program, where I have define 5 different character arrays, and I am Initializing the *path[] with these arrays, and the program works fine. */ char a1[]="/usr/pgmr/blm/citoh/shit"; char a2[]="/usr/pgmr/junk"; char a3[]="/usr/lib/news/history"; char a4[]="/usr/bin/vi"; char bad_address[] = "Testing Initialization"; char null[]="" ; char *path[6] = { a1, a2, a3, a4, bad_address, null }; char **p_path = path ; /* pointer to path */ main() { /*path[0] = a1, path[1] = a2, path[2]=a3, path[3]=a4 ;*/ while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program4.c */ /***************/ /* Still consider another program, where I have define 5 different character pointers, and I am Initializing the *path[] with these pointers, and the program works fine. */ char *a1="/usr/pgmr/blm/citoh/shit"; char *a2="/usr/pgmr/junk"; char *a3="/usr/lib/news/history"; char *a4="/usr/bin/vi"; char *bad_address = "Testing Initialization"; char *null="" ; char *path[6] = { a1, a2, a3, a4, bad_address, null }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /* I am getting the following errors: "program3.c", line 18: illegal initialization "program3.c", line 19: illegal initialization "program3.c", line 20: illegal initialization "program3.c", line 21: illegal initialization "program3.c", line 22: illegal initialization "program3.c", line 24: illegal initialization */ Questions : . What subtle difference program3.c & program4.c has ? . Why character arrays can be used to initialize the array of pointers to character & character pointers cannot be used to initialize the array of pointers to characters ? -- blm!spec0 Bharat Madhyani
blm@spec0.UUCP (Bharat Lal Madhyani) (05/06/89)
Please ignore my previous posting. This is the most recent posting. There were some type-errors in the previous one. Sorry :-) /*************/ /* program1.c*/ /*************/ /* consider the following small c_program path : is an array of pointers to characters, which has been initialized p_path : is a pointer to path, i.e it is a pointer to pointer to character The program basically travels the array path and prints the character string associated with the pointer at that time. */ char *path[] = { "/usr/pgmr/blm/citoh/shit", "/usr/pgmr/junk", "/usr/lib/news/history", "/usr/bin/vi", "Testing Initialization", 0 }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program2.c */ /***************/ /* In this program , I have defined a new variable bad_address -- which is a pointer to character. And while initializing the path array of pointers to characters I am getting the following error : "program2.c", line 30: illegal initialization why it is so ? bad_address is also an address(pointer), which also points to character string. And as we all know that two dimensional array are implemented through pointers, i.e char a[10][20] means : a is an array of 10 pointers, and each element of array a is an array of 20 characters. */ char *bad_address = "Testing Initialization"; char *path[] = { "/usr/pgmr/blm/citoh/shit", "/usr/pgmr/junk", "/usr/lib/news/history", "/usr/bin/vi", bad_address, /* Here is illegal initialization */ 0 }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program3.c */ /***************/ /* Still consider another program, where I have defined 5 different character arrays, and I am Initializing the *path[] with these arrays, and the program works fine. */ char a1[]="/usr/pgmr/blm/citoh/shit"; char a2[]="/usr/pgmr/junk"; char a3[]="/usr/lib/news/history"; char a4[]="/usr/bin/vi"; char bad_address[] = "Testing Initialization"; char null[]="" ; char *path[6] = { a1, a2, a3, a4, bad_address, null }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /***************/ /* program4.c */ /***************/ /* Still consider another program, where I have defined 5 different character pointers, and I am Initializing the *path[] with these pointers, and the program does not compile due to illegal initialization. */ char *a1="/usr/pgmr/blm/citoh/shit"; char *a2="/usr/pgmr/junk"; char *a3="/usr/lib/news/history"; char *a4="/usr/bin/vi"; char *bad_address = "Testing Initialization"; char *null="" ; char *path[6] = { a1, a2, a3, a4, bad_address, null }; char **p_path = path ; /* pointer to path */ main() { while ( **p_path ) printf("%s\n", *p_path++ ); } /* I am getting the following errors: "program3.c", line 19: illegal initialization "program3.c", line 20: illegal initialization "program3.c", line 21: illegal initialization "program3.c", line 22: illegal initialization "program3.c", line 23: illegal initialization "program3.c", line 24: illegal initialization */ Questions : . What subtle difference program3.c & program4.c has ? . Why character arrays can be used to initialize the array of pointers to character & character pointers cannot be used to initialize the array of pointers to characters ? -- spec0!blm Bharat Madhyani
guy@auspex.auspex.com (Guy Harris) (05/07/89)
>/* > In this program , I have defined a new variable > bad_address -- which is a pointer to character. And > while initializing the path array of pointers to characters > I am getting the following error : > > "program2.c", line 30: illegal initialization > > > why it is so ? bad_address is also an address(pointer), which also > points to character string. And as we all know that two > dimensional array are implemented through pointers, i.e > char a[10][20] means : > > a is an array of 10 pointers, and each element of > array a is an array of 20 characters. Uh, speak for yourself here, not for "us all". Many of us know no such thing, because it's simply not true; "char a[10][20]" means "a is an array of 10 arrays of 20 characters" - period. Arrays are not pointers. The problem with the initialization in question, however, has nothing to do with this. "bad_address" is, indeed, a variable of type "pointer to char", and therefore its value is of the right type to stuff into a member of "path", since "path" is an array of pointers to "char". However, it is a *variable*, not a *constant*, and therefore it can't be used in an initialization of a static variable such as "path". >/***************/ >/* program3.c */ >/***************/ >/* > Still consider another program, where I have define 5 different > character arrays, and I am Initializing the *path[] with these > arrays, and the program works fine. That's because "a1", "a2", etc. are arrays of "char", unlike "bad_address", which is a variable of type "pointer to char". In most (but *NOT* all) contexts, an expression of type "array of <type>" gets converted to an expression of type "pointer to <type>" which points to the first element of the array in question, so in those contexts "a1", which is an expression of type "array of char", gets converted to an expression of type "pointer to char" that points to the first element of "a1", and the same is true for "a2", "a3", "a4", "bad_address", and "null". Since "a1", etc. are static variables, the expression resulting from that conversion is a constant expression, and thus can be used in the initialization of a static variable such as "path". This means that char bad_address[] = "Testing Initialization"; and char *bad_address = "Testing Initialization"; are *NOT* equivalent. The first defines an array of "char", named "bad_address"; that array is big enough to hold the string "Testing Initialization", complete with the trailing '\0', and is initialized to that string. The second creates an array of "char", with no name, which is big enough to hold the string "Testing Initialization", complete with the trailing '\0', and which is initialized to that string; it defines a pointer to "char", named "bad_address", which is initialized to a pointer to the aforementioned unnamed array. >/* > Still consider another program, where I have define 5 different > character pointers, and I am Initializing the *path[] with these > pointers, and the program works fine. Same problem as before; "a1", "a2", etc. are *not* constant expressions, so they cannot be used to initialize static variables such as "path". >. Why character arrays can be used to initialize the array > of pointers to character & character pointers cannot be > used to initialize the array of pointers to characters ? Because a character array of static storage duration, when converted to a pointer in those contexts where such a conversion is performed, is a constant expression (said array is, after all, assigned a fixed address at compile, link, or possibly execute time), while a character pointer variable is *not* a constant expression. Only constant expressions can be used to initialize objects of static storage duration.
gwyn@smoke.BRL.MIL (Doug Gwyn) (05/08/89)
In article <386@spec0.UUCP> blm@spec0.UUCP (Bharat Lal Madhyani) writes: > why it is so ? bad_address is also an address(pointer), which also > points to character string. No, it doesn't. It points to a character (the first member of the array generated for the string literal).
gwyn@smoke.BRL.MIL (Doug Gwyn) (05/08/89)
In article <387@spec0.UUCP> blm@spec0.UUCP (Bharat Lal Madhyani) writes: >char *bad_address = "Testing Initialization"; >char *path[] = { > bad_address, /* Here is illegal initialization */ >}; Yes, because such initializers have to be known at compiler/link time, not run time, the initializers must be constant expresions, not contents of storage locations.
rkl@cbnewsh.ATT.COM (kevin.laux) (05/08/89)
In article <386@spec0.UUCP>, blm@spec0.UUCP (Bharat Lal Madhyani) writes: [stuff deleted] > And as we all know that two > dimensional array are implemented through pointers, i.e > char a[10][20] means : > > a is an array of 10 pointers, and each element of > array a is an array of 20 characters. > > */ [stuff deleted] No! Array a is *NOT* an array of 10 pointers and does *NOT* mean it either. Array a is a two-dimensional array of chars, period. When you write: char *path[10]; *That* is an array of 10 pointers to chars. --rkl
throopw@dg-rtp.dg.com (Wayne A. Throop) (05/13/89)
> blm@spec0.UUCP (Bharat Lal Madhyani) Everybody pointed out that the type (int [N][M]) is NOT implemented as an array of pointers. But nobody seemed to see the problem in the first program (shown here abbreviated): > char *path[] = { > "/usr/pgmr/junk", > [...] > 0 }; > char **p_path = path ; /* pointer to path */ > main() { while ( **p_path ) printf("%s\n", *p_path++ ); } Does nobody see anything wrong with the condition of that while loop? Anybody? Yes, you in the back with the plastic pocket protector? That's right, it dereferences the null pointer. It may work on some machines, but it is NOT portable at all. Later examples in the same posting get this right, by replacing the zero with an empty string. The other way to correct it is to make the test on (*p_path) instead of (**p_path). -- "You'd be surprised... they're all separate little countries down there." --- Ronald Wilson Reagan Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
jwl@sag4.ssl.berkeley.edu (Jim Lewis) (06/16/91)
In article <33641@usc.edu> burzin@skat.usc.edu (Burzin N. Engineer) writes: >Hi, > I just gave an interview which had a C quiz and there was this program >that really confused me. I have compiled the program and can still not figure >out what is going on. Any reference or help will be appreciated. >--- >char *c[] = { > "ENTER", > "NEW", > "POINT", > "FIRST" > }; >char **cp[] = { c+3, c+2, c+1, c}; >char ***cpp = cp; >main() >{ > printf("%s", *++cpp); > printf("%s", *--*++cpp+3); > printf("%s", *cpp[-2]+3); > printf("%s\n", cpp[-1][-1]+1 ); >} > >When run it produces: >ERSTEW Part of the reason this quiz question didn't make much sense is because it has a bug in it. The first string printed should be **++cpp, not *++cpp. The output will then be "POINTERSTEW". Without the missing pointer dereference, it's taking a piece of memory that holds a pointer, and trying to print that sequence of bytes as a string. On your architecture, the first byte of the pointer was probably zero, which is the end-of-string marker, so the first printf was a no-op. Under a different byte ordering, you might have seen some garbage characters, or perhaps a core dump. I won't spoil the puzzle for you...you should go back to your C reference and re-read the sections on arrays and pointers until you see what's going on. It's good to be able to understand what's going on with these programs, but I'd be pretty leery of an employer that relied heavily on these kinds of quiz questions to test someone's knowledge of C. (I could see one or two questions like this to seperate the truly outstanding candidates from the merely competent, but a whole test like that? *shudder*!) Both problems (including the POINTER STEW bug) came from "The C Puzzle Book" by Alan R. Feuer. This isn't the first time they've been mentioned on the net by people who ran across them at interviews....maybe the companies who are using this book to test programmers should wise up and switch to winners (or losers!) of recent Obfuscated C contests! -- Jim Lewis, U.C. Berkeley Center for EUV Astrophysics
scs@adam.mit.edu (Steve Summit) (06/18/91)
In article <1991Jun15.223427.13656@agate.berkeley.edu> jwl@sag4.ssl.berkeley.edu (Jim Lewis) writes: >Both problems (including the POINTER STEW bug) came from "The C Puzzle >Book" by Alan R. Feuer. This isn't the first time they've been mentioned >on the net by people who ran across them at interviews... I would never work for such a company. Steve Summit scs@adam.mit.edu
snk@garage.uucp (Samuel Kamens) (06/19/91)
In article <1991Jun18.163802.25891@athena.mit.edu> scs@adam.mit.edu writes: >In article <1991Jun15.223427.13656@agate.berkeley.edu> jwl@sag4.ssl.berkeley.edu (Jim Lewis) writes: >>Both problems (including the POINTER STEW bug) came from "The C Puzzle >>Book" by Alan R. Feuer. This isn't the first time they've been mentioned >>on the net by people who ran across them at interviews... > >I would never work for such a company. > Actually, I understand that this practice is illegal. Using anything but an instrumented test for employment purposes in discrimination, and is therefore against the law (my source for this is a recent class I took in interviewing practices at work....). [ boy is this *not* comp.lang.c-appropriate. Sorry.....] ------------------------------------------------------------------------------- Sam Kamens Bell Communications Research snk@bae.bellcore.com Phone: (908) 699-7381 444 Hoes Lane Room RRC 1C-205 Piscataway, NJ 08854 -- ------------------------------------------------------------------------------- Sam Kamens Bell Communications Research snk@bae.bellcore.com Phone: (908) 699-7381