void and this

  • Thread starter Jonathan Mcdougall
  • Start date
W

WW

David said:
No, because A) you asked a loaded question, and B) I don't
think the issue has an unarguably correct position.

Good. Then please, by all means, continue ranting. I will, in no way,
stand in the way of anyones happiness.
 
J

jeffc

David B. Held said:
Attila Feher said:
[...]
And as everything redundant adding no value, the only
thing it can add is error, misunderstanding, misleading,
wondering collegagues why is it there and so forth.
[...]
Yes, he is. I wish he would stop trolling.

So you're saying your statement above about (void) has a
factual basis? Would you like to prove your statement then,
with replicated studies? Or are you just going to admit
that you made a provokative unfounded claim?

He is never going to admit *anything*, *ever*. After 1 or 2 more ludicrous
posts of his, he's going into the killfile.
 
B

Bob Bell

It's a good thing it was reincorporated, then. If I remember
correctly, there are contexts where foo() can be (mis)interpreted as a
call to foo() rather than a declaration of it; that never occurs with
foo(void).

(It's a subtle issue with templates, but I'll have to post an example
when I get home, as I don't have my copy of C++ Templates: The
Complete Guide. On the other hand, I might be remembering it wrong.)

D'oh! Looks like I'm remembering it wrong. I had this confused with a
different subtle issue with templates.

Bob
 
S

Simon Elliott

David B. Held said:
To each his own. When I see (int) 3.14, I think "C". But that's
because there's a *better* way to do it in C++. When I see
"(void)", I *don't* think "C", because the "C++ Way" isn't
technically better. It's just different.

Much as I hate to jump in to a controversial thread like this, some of
this stuff is interesting, and some is actually quite relevant to code I
have to maintain and develop.

I'm involved in several projects where there's a core lump of C code.
Sometimes this is legacy stuff which is so tried and tested that it
would be foolish to replace it. More often it's cross platform and must
work on a a variety of embedded systems with low power 8 bit processors.
Often these don't have C++ compilers, and even if they did, the
developers probably wouldn't want to use C++.

If this core C code is to be callable from larger, more complex programs
written with C++, there has to be some kind of interface between the C
and the C++. Sometimes it's necessary for C code to call C++ functions
or vice versa, and sometimes it's necessary to #include data structures
which were originally written for the core C code. So I end up having a
certain amount of this kind of thing:

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

extern BLOGGS* BLOGGSnew(void);
extern void BLOGGSdelete(BLOGGS* pBloggs);
extern void BLOGGSsetFoo(BLOGGS* pBloggs, int iFoo);

#ifdef __cplusplus
}
#endif /* __cplusplus */

You can see where I'd be a bit worried about disappearance from the
standard of the use of 'void' to indicate a null argument list. So here
are a few more comments and questions around the topic of C versus C++.

1/ Do those who don't like the use of 'void' to indicate a null argument
list also think that 'void' should be dropped as a return type to
indicate a function which doesn't return a value? It seems a bit strange
that a function with no specified return type should default to int
rather than void.

2/ I find the change in the names of the standard headers from "stdio.h"
to "cstdio" are also quite disturbing. Is the long term objective of the
C++ standard still to encompass being "a better C"?

3/ One of the biggest problems I have when I need to #include headers
written for C is that the C developer will often have written:
typedef int bool;
Which not surprisingly C++ compilers don't like. Guarding the
declaration with #ifdef __cplusplus doesn't help if the developer has
then used his bool type in argument lists or structures, as sizeof(int)
in the C compiler isn't likely to be the same as sizeof(bool) in the C++
compiler. How would people get round this?

4/ Interesting point by David re C casts. When I code in C++ I use the
new C++ casts for objects, but if I'm just converting one built in type
to another, I'll use a C cast: int i; i=(int)3.14;
Is there any downside to this use of C casts in C++ code?
 
A

Attila Feher

Simon Elliott wrote:
[SNIP]
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

extern BLOGGS* BLOGGSnew(void);
extern void BLOGGSdelete(BLOGGS* pBloggs);
extern void BLOGGSsetFoo(BLOGGS* pBloggs, int iFoo);

#ifdef __cplusplus
}
#endif /* __cplusplus */

You can see where I'd be a bit worried about disappearance from the
standard of the use of 'void' to indicate a null argument list. So
here are a few more comments and questions around the topic of C
versus C++.

It will not disappear. The question was about its use in "pure C++" code.
1/ Do those who don't like the use of 'void' to indicate a null
argument list also think that 'void' should be dropped as a return
type to indicate a function which doesn't return a value?

This has nothing to do with the topic, and no one suggested void to be
dropped.
It seems a
bit strange that a function with no specified return type should
default to int rather than void.

That might be the reason no one has suggested anything silly like that. Not
even for indication of an empty argument list.
2/ I find the change in the names of the standard headers from
"stdio.h" to "cstdio" are also quite disturbing. Is the long term
objective of the C++ standard still to encompass being "a better C"?

It has never been. C++ is a stand alone language, with high (but not full)
compatibility with C. There was a long list of articles/statement/threads
(in comp.lang.c++.moderated) about C and C++ compatibility, and the need to
increase it. There is a legit need and there seems to be a serious
intention (at least from some, including Bjarne Stroustrup) to make that
happen. How, when - if ever - is still a question.
3/ One of the biggest problems I have when I need to #include headers
written for C is that the C developer will often have written:
typedef int bool;
Which not surprisingly C++ compilers don't like. Guarding the
declaration with #ifdef __cplusplus doesn't help if the developer has
then used his bool type in argument lists or structures, as
sizeof(int) in the C compiler isn't likely to be the same as
sizeof(bool) in the C++ compiler. How would people get round this?

Interesting. I think it is not really possible without changing the C code,
like calling that typedef cbool or something.
4/ Interesting point by David re C casts. When I code in C++ I use the
new C++ casts for objects, but if I'm just converting one built in
type to another, I'll use a C cast: int i; i=(int)3.14;
Is there any downside to this use of C casts in C++ code?

Some. For example it is much harder to find them (like text search). But I
think in the above code you need no cast... do you? Unless you supress a
warning...

I do not think that such a cast (as above) is dangerous. C++ programmers
will need to learn the C style casts, they are not deprecated and they will
be around for quite a while. (Not deprecated IMO means that they will be
around for at least 20 years.)

Casts which really do something IMO better be written as C++ style casts.
But as I understand this is exactly what you do. :)
 
F

Frank Schmitt

Simon Elliott said:
1/ Do those who don't like the use of 'void' to indicate a null argument
list also think that 'void' should be dropped as a return type to
indicate a function which doesn't return a value?

I don't like the usage of void to indicate a null argument list, but I
insist on having void as return type for functions not returning
anything - otherwise parsing C++ (for a human, at least) would become
more difficult.
It seems a bit strange
that a function with no specified return type should default to int
rather than void.

Functions without a specified return type are no longer allowed in C++.
4/ Interesting point by David re C casts. When I code in C++ I use the
new C++ casts for objects, but if I'm just converting one built in type
to another, I'll use a C cast: int i; i=(int)3.14;
Is there any downside to this use of C casts in C++ code?

They are much harder to spot - for the new style casts, a simple grep
suffices. That said, for trivial cases like yours, I tend to use C-style
casts as well - less typing :)

kind regards
frank
 
G

Gavin Deane

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

extern BLOGGS* BLOGGSnew(void);
extern void BLOGGSdelete(BLOGGS* pBloggs);
extern void BLOGGSsetFoo(BLOGGS* pBloggs, int iFoo);

#ifdef __cplusplus
}
#endif /* __cplusplus */

You can see where I'd be a bit worried about disappearance from the
standard of the use of 'void' to indicate a null argument list. So here
are a few more comments and questions around the topic of C versus C++.

I don't think it's likely to disappear is it?
1/ Do those who don't like the use of 'void' to indicate a null argument
list also think that 'void' should be dropped as a return type to
indicate a function which doesn't return a value? It seems a bit strange
that a function with no specified return type should default to int
rather than void.

Those who don't like the use of 'void' to indicate an empty parameter
list are arguing from a purely C++ point of view. A function with no
specified return type is not allowed in C++ - there is no implicit
int. Allowing functions that don't return anything to be defined
without any return type at all (no void, no anything) would be a
fundamental change and I'm sure nobody is suggesting that.
2/ I find the change in the names of the standard headers from "stdio.h"
to "cstdio" are also quite disturbing. Is the long term objective of the
C++ standard still to encompass being "a better C"?

stdio.h hasn't been replaced by cstdio. The old headers are still
available. The new headers put the library in namespace std which is
good for pure C++, but not when your code needs to be compiled as both
C and C++. I don't think the stdio.h style headers are any more likely
to disappear than allowing void to indicate an empty parameter list
is.
3/ One of the biggest problems I have when I need to #include headers
written for C is that the C developer will often have written:
typedef int bool;
Which not surprisingly C++ compilers don't like. Guarding the
declaration with #ifdef __cplusplus doesn't help if the developer has
then used his bool type in argument lists or structures, as sizeof(int)
in the C compiler isn't likely to be the same as sizeof(bool) in the C++
compiler. How would people get round this?

Not sure there is an easy way around that. If you're writing code that
you expect to be compiled as C and as C++, I suppose you just have to
not do that. Doesn't C99 have a built in boolean type now?
4/ Interesting point by David re C casts. When I code in C++ I use the
new C++ casts for objects, but if I'm just converting one built in type
to another, I'll use a C cast: int i; i=(int)3.14;
Is there any downside to this use of C casts in C++ code?

The new C++ casts are preferred for two reasons. They are easier to
spot, both by humans and by search tools. And, probably more
importantly, all apart from reinterpret_cast are less powerful than
C-style casts, allowing the compiler to still do a certain amount of
type checking.

I have the impression that well written C code is likely to contain
more casts (particularly pointer casts) than well written C++ code.
But I am not a C programmer so I may have got that idea simply from
seeing code from people who aren't as good as they think they are.

GJD
 
D

Dave Vandervies

<snip description of working with C and C++ code close together>

Not sure there is an easy way around that. If you're writing code that
you expect to be compiled as C and as C++, I suppose you just have to
not do that. Doesn't C99 have a built in boolean type now?

C99 has a built in boolean type (_Bool), as well as a standard header
(<stdbool.h>) that defines macros for bool, true, and false.

Since in practice you're unlikely to be able to avoid having to coexist
with C90 for quite some time, this doesn't make it any easier to use
bool in headers that have to be both C- and C++-clean. It's probably
still best to use int and document that the value represents a boolean
value for that.

The new C++ casts are preferred for two reasons. They are easier to
spot, both by humans and by search tools. And, probably more
importantly, all apart from reinterpret_cast are less powerful than
C-style casts, allowing the compiler to still do a certain amount of
type checking.

Also useful is that they do better with indicating why a cast is used.
F'rexample:

free((void *)temp);

Is the programmer not aware that conversions to void * don't need
a cast? Is temp const- or volatile-qualified for some reason? Is temp
a non-pointer type that has had a pointer stuffed in it?

Now answer the same question for:

free(const_cast<void *>(temp));

(I've encountered this in testing code that used a volatile-qualified
pointer obtained from malloc to avoid having some timing tests optimized
out. Perhaps not the best example, since the total amount of code for
such things tends to be small enough that it's easy to find supporting
evidence for "casting away qualifiers", but still enough to demonstrate
the point.)

I have the impression that well written C code is likely to contain
more casts (particularly pointer casts) than well written C++ code.
But I am not a C programmer so I may have got that idea simply from
seeing code from people who aren't as good as they think they are.

Most likely the latter.

There are a very small number of cases where a cast is required, but they
tend not to be the places most programmers use them. (In my experience,
the most important use of casts is to shut up compiler warnings for
conversions that can lose information, like double->float.) Pointer
casts especially are almost always a sign that the code needs a closer
look and probably some debugging.
C tends to use fewer pointer conversions than C++ in the first place,
and the most common one (void * returned from malloc -> pointer used
to point to stuff -> void * passed to free) is done without a cast.
(Note that void * has a somewhat different purpose in C than in C++,
and corresponding differences in rules for its use.)

(For the curious, the places where pointer casts are actually valid and
useful in C (that I know of) are:
-Passing pointers as variadic arguments where the type of the pointer
isn't the expected type. The canonical example of this is printf's
"%p", which expects a void *, and there isn't enough type information
to allow an automatic conversion.
(Not as relevant in C++, since there's usually a better way to do
things than using variadic functions)
-Casting away const for functions that return a pointer to the same
thing as a pointer they're passed, without modifying what's pointed
at (several <string.h> functions do this or the moral equivalent).
(Not useful in C++, because of stronger const rules and overloading:
C's "char *return_pointer_into_string(const char *)" would have two
versions in C++, one taking and returning char * and one taking and
returning const char *)
-Taking advantage of the rule that a pointer to a struct, suitably
converted, can be used as a pointer to its first member. This usually
means the programmer is doing something odd anyways.
(Valid (as far as I know) and potentially useful in C++, but most
often used to allow a limited form of polymorphism that in C++ is
better done using other language features)
-Converting a pointer to char * to examine the representation of an object
(Just as valid, and just as useful (that is, "not portably"), in C++
as in C)
If you really want to know all the details, ask in comp.lang.c .)


dave
 
E

E. Robert Tisdale

Dave said:
C99 has a built in boolean type (_Bool), as well as a standard header
(<stdbool.h>) that defines macros for bool, true, and false.

Since in practice you're unlikely to be able to avoid having to coexist
with C90 for quite some time, this doesn't make it any easier to use
bool in headers that have to be both C- and C++-clean.
It's probably still best to use int and document that
the value represents a boolean value for that.

This is *bad* advice.

C90 programmers should provide their own stdbool.h header file:

#ifndef guard_stdbool_h
#define guard_stdbool_h 1
typedef int bool;
const int false = 0;
const int true = !false;
#endif/*guard_stdbool_h */
 
D

Dave Vandervies

This is *bad* advice.

C90 programmers should provide their own stdbool.h header file:

#ifndef guard_stdbool_h
#define guard_stdbool_h 1
typedef int bool;
const int false = 0;
const int true = !false;
#endif/*guard_stdbool_h */

And how does this make it easier to have headers that can be used with
C90, C99, *and* C++?
Unless there are constraints on C++'s bool that I'm not aware of, it
would be reasonable to expect C++'s bool and C99's _Bool to be the same
type for a compiler that supports both languages. Expecting this to
be the same as int is less reasonable, and without all three being the
same it becomes pointless to use "bool" in headers that are intended to
be used between the languages.

Do you have an alternate suggestion for being able to put this in a
header file:
--------
void do_something_with_boolean_value(bool);
--------
and being able to correctly call do_something_with_boolean_value from
any of the three languages?


Aside from interoperability issues that can be confined to header files,
C90 programmers should write in C90, which doesn't include a boolean type
(though it does allow one to be created if it's desired, and with care
the semantics of such a type (if not the representation) can be made
compatible with those of the bool from C99's <stdbool.h>).


dave
 
E

E. Robert Tisdale

Dave said:
And how does this make it easier to have headers that can be used with
C90, C99, *and* C++?
Unless there are constraints on C++'s bool that I'm not aware of, it
would be reasonable to expect C++'s bool and C99's _Bool to be the same
type for a compiler that supports both languages. Expecting this to
be the same as int is less reasonable, and without all three being the
same it becomes pointless to use "bool" in headers that are intended to
be used between the languages.

Do you have an alternate suggestion for being able to put this in a
header file:
--------
void do_something_with_boolean_value(bool);
--------
and being able to correctly call do_something_with_boolean_value from
any of the three languages?


Aside from interoperability issues that can be confined to header files,
C90 programmers should write in C90, which doesn't include a boolean type
(though it does allow one to be created if it's desired, and with care
the semantics of such a type (if not the representation) can be made
compatible with those of the bool from C99's <stdbool.h>).

You are confusing interoperability with portability.
None of the ANSI/ISO C and C++ standards guarantee interoperability.
There in *no* guarantee that you can link in object files
created by any other C or C++ compiler
and get the code to run correctly.

Portability guarantees *only* that you can compile and link together
object files created by the same compiler.
Programmers who have only a C90 compiler should provide
or should be provided with an stdbool.h header file
like the one shown above, include it in their programs
and use the bool type and the false and true constants.

Programmers who have a C99 compiler will use the stdbool.h header file
that came with their compiler.

Programmers who have a C++ compiler
must provide an empty stdbool.h header file
and the compiler will use the built-in type bool.
 
T

Tom Plunket

Just to resurrect an old old thread, since this same thread came
up at work just recently and now I wish to spark more discussion.

Rolf said:
How does adding a pseudo parameter of type void make it more expicit
that you want no parameters?

The question that came up in my mind is that this "pseudo
parameter" isn't pseudo at all. It means, quite explicitly, that
the function takes no parameters.

While I understand that empty parentheses means "takes no
parameters," doesn't this beg the question (compatibility with
the first C aside) of why a function that takes no parameters
needs to have 'void' stated as its return type? I mean, if we're
trying to get rid of useless typing, certainly a function that
returns nothing (indeed, a function that doesn't even have an
explicit return statement) shouldn't need to specify that it
returns nothing- it could just get away with not stating that it
returns something.

To pull it all together, putting void in the parameters list is
only as silly (IMO) as putting void as the return type. Alas, I
still don't use void between the parens, but now see a lack of
symmetry in the way type specifiers are used.

Does my logic fail, besides contradicting The Almighty Standard?


-tom!
 
P

Peter Koch Larsen

Tom Plunket said:
Just to resurrect an old old thread, since this same thread came
up at work just recently and now I wish to spark more discussion.
[snip]

While I understand that empty parentheses means "takes no
parameters," doesn't this beg the question (compatibility with
the first C aside) of why a function that takes no parameters
needs to have 'void' stated as its return type? I mean, if we're
trying to get rid of useless typing, certainly a function that
returns nothing (indeed, a function that doesn't even have an
explicit return statement) shouldn't need to specify that it
returns nothing- it could just get away with not stating that it
returns something.

For historical reasons, a function that did not specify a return type was
assumed to return int. This is not the case in C++ and probably not in C
eiter.
To pull it all together, putting void in the parameters list is
only as silly (IMO) as putting void as the return type. Alas, I
still don't use void between the parens, but now see a lack of
symmetry in the way type specifiers are used.

Does my logic fail, besides contradicting The Almighty Standard?

You could easily imagine a language where no return-type was equivalent to a
void return. Forgetting your inheritance is not a good thing, however.


Kind regards
Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top