From: umagnum338 on
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

<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
"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
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
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
 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11
Prev: PF_INET vs. AF_INET
Next: grep