C++/VB - "PORTING C" > NULL problem!

Asked By Robby
08-Feb-10 06:30 PM
Hello,

As you all know, I used to use a non C compliant compiler. Now in the new C
compiler, I declared a NULL in a header file like this:


so I could pass NULL as a function parameter... stuff like this:

void f1(var1, NULL);  ..... and so forth.

I recently upgraded the compiler's version and now this still works but the
compiler gives the follwoing warnings

KERNEL.h:53:1: warning: "NULL" redefined
In file included from C:/Program Files (x86)/Microchip/MPLAB C32
Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/GenericTypeDefs.h:58,

from C:/Program Files (x86)/Microchip/MPLAB C32
Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/peripheral/i2c.h:50,

from C:/Program Files (x86)/Microchip/MPLAB C32
Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/plib.h:46,

C:/Program Files (x86)/Microchip/MPLAB C32
Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/stddef.h:67:1:
warning: this is the location of the previous definition

which I think means they have added a new definition of NULL in one of their
files of their new compiler's version. So on the last warning above I double
clicked on it an it took me to the following line of the stddef.h file:

... other code
...other code

Now I know this question is probably better posted in the compiler's
specific forum, but I would like to ask something about the language. What
does this say exactly:


NULL is a void pointer?? which still means 0 right?
So if I use NULL anywhere, I am substituting it by 0 right?

Why would someone do this as opposed to just do this:


All feedback greatly appreciated!

--
Best regards
Roberto
GenericTyp
(1)
GmbH
(1)
Boekelheide
(1)
Amtsgericht
(1)
Providenza
(1)
Cheeezzze
(1)
Microchip
(1)
Thorsten
(1)
  Igor Tandetnik replied to Robby
08-Feb-10 07:49 PM
new C

Do you have to? NULL should be defined in standard headers that come =
with any decent C compiler.

but the
Suite/bin/../lib/gcc/pic32mx/3.4.4/../../../../pic32mx/include/GenericTyp=
eDefs.h:58,

Precisely my point.

What

0 cast to void*


In C, typically, yes.


I am not sure I understand this question.

This is what C standard has to say:

6.3.2.3p3 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.

6.3.2.3p4 Conversion of a null pointer to another pointer type yields a =
null pointer of that type. Any two null pointers shall compare equal.

Footnote 55) The macro NULL is defined in <stddef.h> (and other headers) =
as a null pointer constant; see 7.17.



This is equally valid, and in fact this is how it is usually done in C++ =
( ((void*)0) does not work in C++ because void* pointer is not implicitly =
convertible to other pointer types, the way it is in C). One possible =
reason to use ((void*)0) is that you would expect sizeof(NULL) to be =
equal to sizeof(void*) and not sizeof(int) (pointers do not have to be =
the same size as int).
--=20
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925
  Robby replied to Igor Tandetnik
08-Feb-10 09:20 PM
hum! Well, what if I do this for my own null:


I do this because sometimes I have a function's parameter that takes an
integer. Now, in this function, if this integer is 1 it will do one thing, if
its 2, it will do another and if its 3, it will do even another, but if its
0, it will reset some stuff and do none of the the other things. So sometimes
its possible that I would need that integer to be passed in as 0, so I call
the function like this:

void f1(NULL);

well now it will be:

void f1(null);

or I could simply do:

void f1(0);

But then, at first glance when I look at the latter function, I think that
the function  does some mathematical operation..... instead if I look at the
former, I know that that parameter is used to carry out a certain mode of
operation in the function. So what is best in these types of scenarios?


Isn't a void pointer's value 0 ? Or should I ask, what is the difference
between a void pointer's value and the value of 0.





Thanks Igor.
  Pavel A. replied to Robby
08-Feb-10 09:43 PM
By convention (or even by standard?),  NULL is null pointer, not numeric 0.
For what you want, there are  enums:

enum xxxx {
reset_some stuff = 0,
do_one_thing= 1,
........ etc.........
}

f( reset_some stuff );

--pa
  Igor Tandetnik replied to Robby
09-Feb-10 12:11 AM
the new C
with any decent C compiler.
an

I would not if I were you. You would not use the word "apple" to describe =
an orange: it makes equally little sense to use the word "null" to =
describe something other than a null pointer.

if its

As Pavel notes, you want an enum.


I am not sure what you mean by "the value of a pointer".


The former is of type void*, the latter is of type int.
--=20
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925
  Ulrich Eckhardt replied to Robby
09-Feb-10 03:57 AM
A void pointer does not have any type, 'void' is rather a placeholder, but it
does have a value. This value can be null or but it does not have to.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932
  Igor Tandetnik replied to Ulrich Eckhardt
09-Feb-10 07:36 AM
This is not true formally, and I do not think it is useful to think this =
way informally either:
6.2.5p19 The void type comprises an empty set of values; it is an =
incomplete type that cannot be completed.

The type of a void pointer is, of course, void*.
--=20
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925
  Barry Schwarz replied to Igor Tandetnik
09-Feb-10 08:04 AM
Given ptr, a pointer to any object type, the expression ptr == 0 is
well defined by the language.  It will evaluate to true whenever ptr
is a null pointer.  However, whether a pointer is a null pointer
depends on its current value, not its type.  Given the sequence
void *ptr;
ptr = &ptr;
the expression ptr == 0 is guaranteed to evaluate to false.

But this use of the == operator is a special case in the language. The
fact that a pointer can be compared to 0 in no way implies the
representation of the pointer matches that of an int.  Even if the two
objects have the same size, after
int i = 0;
void *p = 0;
i = memcmp(&i, &p, sizeof i);
you still know nothing about the value of i.

Given both of the above, its fair to say the value of a void pointer,
or any other pointer for that matter, is not 0 in the general case. It
is guaranteed to compare to 0 in the specific case using the ==
operator if the pointer has been assigned the null pointer constant
value.


If the pointer points to an object, the value is guaranteed to be
different from 0.


I wonder if the OP stops at null or maybe goes on to define bool as
float or true as 0.  The opportunities to write even more confusing
code are almost boundless.

--
Remove del for email
  Robby replied to Pavel A.
09-Feb-10 11:42 AM
Yes I do this too in my code, but now I feel confirmed that enum is the
right chioce that should be used for this. I use enum alot and I also use
null as a 0 parameter, I think I will stop doing that.

Thanks Pavel.

Rob
  Robby replied to Igor Tandetnik
09-Feb-10 12:20 PM
Yes, understood, that will not be hard to modify my code.


Looks like I am not the only guy that is confused about this, see:

http://www.lysator.liu.se/c/c-faq/c-1.html

Cheeezzze guys, this could get confusing. I can live with the following
simple explanations as quoted from:

http://www.geekinterview.com/talk/1016-void-pointer-in-c-programming-language.html

["
Void is a non-type which has no size, no format, it is a black hole from
which you cannot read. void * is pointer-to-void.

A void pointer is a pointer which can point to any data type (which of
course requires typecasting). Where as a null pointer is used to indicate
that it is pointing nowhere.

A null pointer is a value that any pointer may take to represent that it is
pointing to "nowhere", while a void pointer is a special type of pointer that
can point to somewhere without a specific type. One refers to the value
stored in the pointer itself and the other to the type of data it points to.

But, where is this "nowhere" ???? "Between you and I, everything points to
something, if it points to a location conataining the value of 0, then lets
say it.

Regards
Robert
  Igor Tandetnik replied to Robby
09-Feb-10 03:07 PM
This is architecture-dependent. Usually a null pointer contains an =
invalid address (so that trying to dereference it would be caught by the =
CPU). On most machines, that would be an address of zero. On Windows, =
for example, lower 64K of address space are reserved and would trigger =
an access violation if you try to access any location there: this =
catches most cases where null pointers are misused.


No, not really. There are plenty of addresses in the address space that =
are not dereferenceable - hence the existence of Access Violation.


It does not. A null pointer does not point to any valid location, which =
naturally cannot contain any particular value. Just try it:

int* p =3D NULL;
int x =3D *p;  // see what happens.

--=20
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925
  Pavel A. replied to Igor Tandetnik
09-Feb-10 07:31 PM
There may be a real memory location with adress 0 (either code or data or
both),
so dereferencing "null pointer" may be possible physically - especially
on small microcontrollers like what the OP struggles against.
On most "normal" VM systems, both code and data null locations are
excluded from virtual space of a process, so they cause exception.

.NET has a special nullptr keyword, instead of this controversal 0/NULL
thing.

Regards,
--pa
  Igor Tandetnik replied to Pavel A.
09-Feb-10 07:52 PM
Not on Windows.


That's why I said "architecture-dependent" and "on most machines".

I remember x86 under DOS (real addressing mode, no funny virtual memory =
business) had its interrupt table at address 0 and up. Writing through a =
NULL pointer had rather interesting consequences - suddenly, a random =
memory address became the entry point for some interrupt handler. =
Single-step debugging was implemented via INT 1, so if you managed to =
overwrite that, you would disable your debugger, too. Good times.


C++0x has this, too, but also, inevitably, supports 0 and NULL for =
backward compatibility. VS2010 (coming Real Soon Now) implements various =
parts of C++0x, including nullptr if I recall correctly.
--=20
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not =
necessarily a good idea. It is hard to be sure where they are going to =
land, and it could be dangerous sitting under them as they fly overhead. =
-- RFC 1925
  Robby replied to Igor Tandetnik
11-Feb-10 09:34 AM
That's the under-the-hood explanation I was looking for.
Igor, thankyou very much.

Regards
Roberto
  Ulrich Eckhardt replied to Igor Tandetnik
12-Feb-10 03:05 AM
The type defines the behaviour of an instance, all instances of the same
type share similar behaviour. Since void is incomplete, you can never have
any instances of it. An empty set of values means pretty much the same,
that it cannot exist.

In that context, calling void a placeholder for the lack of a type is a
reasonable description to me. Agreed, it is not formally true, since the C
standard uses a different meaning, but informally that description is
useful.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932
  Stephan T. Lavavej [MSFT] replied to Ulrich Eckhardt
12-Feb-10 05:06 PM
void is an incomplete type and void * is a complete type.

STL
  Tim Roberts replied to Pavel A.
13-Feb-10 03:18 PM
Yes.  NULL is an interesting beast.  Although it is literal bit-pattern
value might not be all zeros, the standard requires that a null pointer
BEHAVE in expressions as though it were the integer 0.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
  Barry Schwarz replied to Tim Roberts
13-Feb-10 06:39 PM
Not at all.  Assuming a prototype for printf in scope,
void *p = 0;
printf("%p\n", p);
would invoke undefined behavior if the null pointer p were to behave
as an int.

A null pointer always behaves like a pointer.  The only time it has
any relation to the integer 0 is when it is being assigned the null
pointer constant value 0 or when it is being compared to the null
pointer constant value 0.  In the latter case one could loosely argue
the pointer is behaving as an integer but the standard makes it very
clear the integer is behaving as a pointer.

--
Remove del for email
  Ulrich Eckhardt replied to Stephan T. Lavavej [MSFT]
15-Feb-10 03:54 AM
...and your point is what?

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932
Create New Account
help
the rationale of this? Vladimir Grigoriev VC Language Discussions CopyFilea (1) CopyFilew (1) CopyFile (1) GmbH (1) Amtsgericht (1) Boekelheide (1) Providenza (1) Stroustrup (1) I am *sure* somebody in 'comp.std.c' might know were not enough existing compilers with min / max implementations. - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. It is strange enough because all old C compilers had usually min / max macros but strong voices against. Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 Ulrich, your position has the ternary operator directly. Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 If you will start GCC release? [Snipped TOFU] Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 As I guess GCC just a compiler, exactly as "pure" as Visual C++. - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. No, Visual C++ is not just a compiler. It is an integrated system which
type is usually equal to the long type? Vladimir Grigoriev VC Language Discussions Database (1) GmbH (1) Amtsgericht (1) Boekelheide (1) Providenza (1) Thorsten (1) Hamburg (1) Windows (1) No. 'long' is 4 bytes, 'long it is not bigger. Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 Thanks, Ulrich. Yesterday I bytes in both 32-bit and 64-bit systems. - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. Actually, that is not completely true. A win64-port must also use a 4 depends on the system. Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 Actually I think it unsigned int ULONG, *PULONG; It depends on the COMPILER. - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. See "Data model": http: / / www.viva64.com / terminology / Data_model.html keywords: The, lomg, long
to LPVOID. Should I be concerned about this? Thanks in advance Nic VC Language Discussions GmbH (1) Boekelheide (1) Amtsgericht (1) Providenza (1) Thorsten (1) Hamburg (1) Sator (1) Uli (1) Probably, and define it as volatile. Uli - - C++ FAQ: http: / / parashift.com / c++-faq-lite Sator Laser GmbH Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932 DECLARE_HANDLE basically defines the to function) to a void pointer and back again. - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. keywords: HWND, to, LPVOID description: Hello In the VS 2005 I have been using
filter ("drop 4 out of 5") available for download? - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc. Win32 DirectX Video Discussions CTransInPlaceFilter (1) Boekelheide (1) Providenza (1) Timr (1) On Fri, 14 Sep 2007 21:28:36 -0700, Tim filter (drop 4 out of 5) available for download - - Tim Roberts, timr@probo.com Providenza & Boekelheide, Inc.?