|
Prev: PF_INET vs. AF_INET
Next: grep
From: umagnum338 on 22 Jun 2005 20:43 Hi, >From the subject you're probably thinking I'm an idiot but I've encountered something that I'm hoping those more experienced than I can answer. At work, I was working my way through a serial testing program that was written a while back and wouldn't build without some help. While trouble shooting I noticed that the program was bailing right from the beginning because main() looked like this: /* include */ int main( int argc, char *argv[] ) { ModemObject M; if( argc == 1 ) { printf( "You must specify a file; e.g. /dev/ttyS0\n" ); return 1; } // continue return 0; } Well, the program (when called with no arguments) wasn't printing the string if argc is 1, so I made the obvious conclusion and began to track down what was happening in ModemObject. Now, this is a C++ program (the calls to printf() notwithstanding) and ModemObject is a class. I noticed there existed only one ctor for the class and it was simple enough. It's a no argument ctor that initializes 3 variables in the class, 2 ints and a pointer. I noticed that the pointer was being initialized to 0. I changed this to NULL and recompiled and walla, the program worked. Now, I'm befuddled. I thought NULL was 0! What gives? As I see it, there are two possibilities. First, either there is some difference between 0 and NULL because of how NULL is defined, or something else took place in the build environment (which is far too complex for such a simple application). The build env starts with a Makefile that recursively calls Makefiles in about 12 subdirectories going about 3 subdirectories deep. As I mentioned, either NULL is slightly different than 0 (because of definition) or in modifying these source code files I changed something that was lacking in previous builds. It is significant to note that the only copy I could tar up of this program was already built, but not functioning in more recent versions of Linux. I couldn't find a source tree that didn't have complied code in it. Suggestions? Thanks, Andy
From: David Schwartz on 22 Jun 2005 21:42 <umagnum338(a)netscape.net> wrote in message news:1119487393.942155.186750(a)g14g2000cwa.googlegroups.com... > Well, the program (when called with no arguments) wasn't printing the > string if argc is 1, so I made the obvious conclusion and began to > track down what was happening in ModemObject. Now, this is a C++ > program (the calls to printf() notwithstanding) and ModemObject is a > class. I noticed there existed only one ctor for the class and it was > simple enough. It's a no argument ctor that initializes 3 variables in > the class, 2 ints and a pointer. I noticed that the pointer was being > initialized to 0. I changed this to NULL and recompiled and walla, the > program worked. This change likely had no effect. Perhaps your first compile was bad somehow, due to using mismatched header files or some similar problem. DS
From: Pascal Bourguignon on 23 Jun 2005 02:20 "David Schwartz" <davids(a)webmaster.com> writes: > <umagnum338(a)netscape.net> wrote in message > news:1119487393.942155.186750(a)g14g2000cwa.googlegroups.com... > >> Well, the program (when called with no arguments) wasn't printing the >> string if argc is 1, so I made the obvious conclusion and began to >> track down what was happening in ModemObject. Now, this is a C++ >> program (the calls to printf() notwithstanding) and ModemObject is a >> class. I noticed there existed only one ctor for the class and it was >> simple enough. It's a no argument ctor that initializes 3 variables in >> the class, 2 ints and a pointer. I noticed that the pointer was being >> initialized to 0. I changed this to NULL and recompiled and walla, the >> program worked. > > This change likely had no effect. Perhaps your first compile was bad > somehow, due to using mismatched header files or some similar problem. Indeed, even if (void*)0 has a different bit pattern than 0, C, and even more so C++, define void* p=0; as setting p to (void*)0, (and p==0 as p==(void*)0). Either you have a bug in the compiler (try to revert to pointer=0), or another gremling. -- __Pascal Bourguignon__ http://www.informatimago.com/ The mighty hunter Returns with gifts of plump birds, Your foot just squashed one.
From: Floyd L. Davidson on 23 Jun 2005 03:30 umagnum338(a)netscape.net wrote: >Hi, > >From the subject you're probably thinking I'm an idiot but I've On the contrary, it happens to be a rather complex and not easy to initially comprehend bit of language definition. Almost everyone at some point has to ask the same question! >the class, 2 ints and a pointer. I noticed that the pointer was being >initialized to 0. I changed this to NULL and recompiled and walla, the >program worked. As others have pointed out, that is very unlikely. There *has* to have been something else to it. >Now, I'm befuddled. I thought NULL was 0! What gives? As I see it, Regardless, nobody else has gone into detail about your question of just what is NULL, so I'm going to. Except, I'm going to explain what it is in the C language, not C++. Perhaps someone else can point out where they differ. There are three distinct entities to be aware of: 1) the /NULL/ macro 2) a /null/ /pointer/ /constant/ 3) a /null/ /pointer/ /NULL/ is a macro, defined in a header file, and is guaranteed to expand in the pre-processor stage to a /null/ /pointer/ /constant/. It is purely a source code device, meant to make source code easier for humans to read. It indicates an invalid address which cannot point to any valid object and will guaranteed compare equal to zero. Note that the C compiler itself *never* sees the NULL, only a /null/ /pointer/ /constant/. A /null/ /pointer/ /constant/ is defined as either an "An integer constant expression with the value 0, or such an expression cast to type void *". This is a source code device. Note that it does not have any particular bit pattern representation, because it exist *only* in the source code. The compiler converts a /null/ /pointer/ /constant/ in the source code to a /null/ /pointer/ value in the output. The /null/ /pointer/ bit pattern is implementation specific. It is whatever the compiler implementor decided to make it. Note that *each* *type* (char, int, long, etc) has it's own /null/ /pointer/ bit pattern, and they are not necessarily the same! (However, the bit pattern commonly is all bits 0 just to make it easy for the compiler implementor. :-) The compiler must guarantee that a /null/ /pointer/ will not equate true when compared to any valid object or function. It must also guarantee that comparing any two /null/ /pointers/ or any /null/ /pointer/ and a /null/ /pointer/ /constant/ will equate true. That can be done by any type of internal magic the implementor wishes to use, and does not mean the actual bit patterns are the same. Here is most of the pertinent part of the C99 Standard, 6.3.2.3 Pointers ... 3 An integer constant expression with the value 0, or such an expression cast to type void *, is called a /null/ /pointer/ /constant/.55) If a /null/ /pointer/ /constant/ is converted to a pointer type, the resulting pointer, called a /null/ /pointer/, is guaranteed to compare unequal to a pointer to any object or function. Footnote 55 says, 55) The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.17. That's a good bit of information to sort out. A couple of things that may not be obvious at first... NULL should *only* be used in a pointer context. "int x = NULL;" is poor style, even if it works. Another, is this: int *p = NULL; /* p now has a null pointer value */ int *p = 0; /* p now has a null pointer value */ int x = 0; p = x; /* p now has a "valid address" equal to 0 */ That is because NULL in converted to a /null/ /pointer/ /constant/ and 0 already is a /null/ /pointer/ /constant/. But x set equal to 0, is just 0. -- Floyd L. Davidson <http://web.newsguy.com/floyd_davidson> Ukpeagvik (Barrow, Alaska) floyd(a)barrow.com
From: Ari Lukumies on 23 Jun 2005 07:49
umagnum338(a)netscape.net wrote: > While trouble shooting I noticed that the program was bailing right > from the beginning because main() looked like this: > > /* include */ > > int main( int argc, char *argv[] ) { > ModemObject M; > > if( argc == 1 ) { > printf( "You must specify a file; e.g. /dev/ttyS0\n" ); > return 1; > } > // continue > return 0; > } > > Well, the program (when called with no arguments) wasn't printing the > string if argc is 1, (which happens only if the program is run without any arguments) > so I made the obvious conclusion and began to > track down what was happening in ModemObject. Now, this is a C++ > program (the calls to printf() notwithstanding) and ModemObject is a > class. I noticed there existed only one ctor for the class and it was > simple enough. It's a no argument ctor that initializes 3 variables in > the class, 2 ints and a pointer. I noticed that the pointer was being > initialized to 0. I changed this to NULL and recompiled and walla, the > program worked. Some of the includes redefined NULL? void *p = NULL; void *p = 0; should yield the same (since, by definition, NULL is defined as (void*)0) - although the latter is recommended in C++ circles. A possibility also is, that the pointer you refer to, is of some class also, and the assignment (or constructor assignment) is redefined to something else with it. Can you show us the class definition of ModemObject and its constructor? We'd be much wiser then. -atl- -- A multiverse is figments of its own creations |