Topic: Defect Report: Definition of void parameter list differs from C


Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Sat, 29 Apr 2006 15:35:01 CST
Raw View
Andrew Koenig wrote:
> "Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
> news:20060422000539.GB6357@decadentplace.org.uk...
>
> > [ Note: Forwarded to C++ Committee. -sdc ]
> >
> > The standard says this about the void parameter list:
> >
> > "The parameter list (void) is equivalent to the empty parameter list."
> > (8.3.5 [dcl.fct] paragraph 2)
>
> Personally, I think it is unfortunate that C defined void to have magical
> properties, and I'd hate to compound the misfortune by requiring that the
> number of parameters in
>
>     int f(T);
>
> depend on the definition of T--especially if T is a template parameter.
>
I agree that it is ugly.
If T, is a typedef, I think that it is not a real problem, since its
type is usually explicit enough.
For instance the VOID type used in the Win32 API is a typedef for void.
And, the Win32 API, uses, at several places, declarations with a (VOID)
parameter list.

For templates, it seems to be a greater problem. But, since the void
type is not assignable, nor instanciable and is very particular. I
can't think of a template that would "work" with the void type...
Indeed, "int f(T)" where T is a void type, is currently ill-formed. So,
accepting the C rule, would just make ill-formed programs,
well-formed... And, in the case of templates, it would probably not
make the program well-formed, because of other problems of void.

My point, is that the C approach, is only ugly for the mind... It'll
not be a practical problem.
On the other side, an incompatibility between C and C++ has concrete
consequences.

And, you probably know that there are much worse context-dependent
semantics, with new.

template <class T>
T* CreateT()
{
return new T;
}

int main() {
typedef char U[42];

U* p=CreateT<U>(); // Beware it returns a char*, not a char(*)[42]
// And you must call delete[] to free it, not delete!
// Fortunately, the compiler will catch, at compile-time, the invalid
conversion from char* to char(*)[42]
}

On the other side, since arrays have no copy-constructor, nor
copy-assignment operator, they can't be used as a normal type...
Fortunately boost::array has none of these problems.

> Here is one way that I imagine could resolve these issues in principle,
> though I doubt it's feasible in practice.
>
> Make void into a real type.  An object of type void contains only a single
> value, written as ().  An empty function argument also generates a void
> value.
>
> Void values can be assigned and copied just like any others.  All six
> relational operators are defined, with ==, <=, and >= returning true and the
> others returning false.
>
> There is no longer any such thing as a function without parameters.  If you
> define
>
>     int f() { return 42; }
>
> that function takes a single parameter of type void.  When you call it as
> f(), the empty argument also has type void.  If you write
>
>     int f(void) { return 42; }
>
> or even
>
>     int f(void foo) { return 42; }
>
> the meaning is exactly the same.
>
> One advantage of this notion is that set<T> starts to look an awful lot like
> map<T,void>, a fact that would surely make library implementation easier.
>

Yes, the idea is pretty, and would be probably useful in templates.
IMHO, it would simplify the language specification, since void would
not be a "special syntax", eveywhere it is used.

Historically, the void type became more and more like another type.
Initially, C had no void type.
Then, the void type has been introduced for return values.
I don't know exactly, when void in typedef appeared... Probably, at the
same time than typedef.
Early C++, introduced void*, and the C comitee borrowed it for the 1989
standard.

With templates, the need for a "copy-constructor" for void, became
obvious.
I mean that:

void g();
void f() {return g();}

Were not allowed in old C and C++ compilers.

> Unfortunatly, I suspect that this idea has too many compatibility problems
> to be feasible at this point.
>
I don't think it will introduce any incompatibility.

However, I'm pretty sure that it would induce many new bugs, in
beginners' code, since ill-formed constructs would become well-defined.

But, any language change needs a strong motivation... Here, the benefit
is probably not negligible, but I'm not sure it is sufficient.
The main motivation I see, is that it would make evolve C++ toward a
cleaner language.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Andrew Koenig" <ark@acm.org>
Date: Mon, 24 Apr 2006 10:49:57 CST
Raw View
"Ben Hutchings" <ben-public-nospam@decadentplace.org.uk> wrote in message
news:20060422000539.GB6357@decadentplace.org.uk...

> [ Note: Forwarded to C++ Committee. -sdc ]
>
> The standard says this about the void parameter list:
>
> "The parameter list (void) is equivalent to the empty parameter list."
> (8.3.5 [dcl.fct] paragraph 2)

Personally, I think it is unfortunate that C defined void to have magical
properties, and I'd hate to compound the misfortune by requiring that the
number of parameters in

    int f(T);

depend on the definition of T--especially if T is a template parameter.

Here is one way that I imagine could resolve these issues in principle,
though I doubt it's feasible in practice.

Make void into a real type.  An object of type void contains only a single
value, written as ().  An empty function argument also generates a void
value.

Void values can be assigned and copied just like any others.  All six
relational operators are defined, with ==, <=, and >= returning true and the
others returning false.

There is no longer any such thing as a function without parameters.  If you
define

    int f() { return 42; }

that function takes a single parameter of type void.  When you call it as
f(), the empty argument also has type void.  If you write

    int f(void) { return 42; }

or even

    int f(void foo) { return 42; }

the meaning is exactly the same.

One advantage of this notion is that set<T> starts to look an awful lot like
map<T,void>, a fact that would surely make library implementation easier.

Unfortunatly, I suspect that this idea has too many compatibility problems
to be feasible at this point.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Sat, 22 Apr 2006 01:12:45 GMT
Raw View
Andrew Pinski helpfully pointed out C DR 157
<http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_157.html> and C++ core
DR 18 <http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#18>,
which confirm my interpretations and there is a difference.  I guess
the fact that DR 18 was closed as NAD doesn't help my case, but the
difference between languages wasn't brought up then.

Ben.

--
Ben Hutchings
One of the nice things about standards is that there are so many of them.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Ben Hutchings <ben-public-nospam@decadentplace.org.uk>
Date: Fri, 21 Apr 2006 21:45:44 -0500
Raw View
[ Note: Forwarded to C++ Committee. -sdc ]

The standard says this about the void parameter list:

"The parameter list (void) is equivalent to the empty parameter list."
(8.3.5 [dcl.fct] paragraph 2)

The C99 standard apparently says something slightly different, though
I'm afraid I'm quoting from a draft here:

"The special case of an unnamed parameter of type void as the only
item in the list specifies that the function has no parameters."
(6.7.5.3 paragraph 10)

If I understand these correctly, this means a C compiler must take
type aliases into account before checking for the special case whereas
a C++ compiler must not.

Comeau C++ in strict mode follows the C++ standard in this regard, as
does the development version of g++ (which will become 4.2), though
older versions of g++ follow the C standard.  During testing of the
new version in Debian, we found that this change broke a C++ program
that uses the OpenAL library, one of whose headers used a type alias
for void in a function parameter list.

Given that this special case only exists in C++ for compatibility with
C, it seems to be a defect in the standard that it is defined slightly
differently.

Ben.

--
Ben Hutchings
Experience is directly proportional to the value of equipment destroyed.
                                                         - Carolyn Scheppner



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Sat, 22 Apr 2006 11:16:54 CST
Raw View
Ben Hutchings wrote:
> [ Note: Forwarded to C++ Committee. -sdc ]
>
> The standard says this about the void parameter list:
>
> "The parameter list (void) is equivalent to the empty parameter list."
> (8.3.5 [dcl.fct] paragraph 2)
>
The C++ standard seems to be pretty clear here : type aliases are
forbidden.

> The C99 standard apparently says something slightly different, though
> I'm afraid I'm quoting from a draft here:
>
> "The special case of an unnamed parameter of type void as the only
> item in the list specifies that the function has no parameters."
> (6.7.5.3 paragraph 10)
>
> If I understand these correctly, this means a C compiler must take
> type aliases into account before checking for the special case whereas
> a C++ compiler must not.
>
I read a bit the C99 standard, and reading 6.7.7 (Type definitions),
and searching whole text for "void type" seems to confirm that a
typedef for the void type, is a void type.
For example 6.5.4-2 (Cast operators) says that:
"Unless the type name speci   es a void type, the type name shall
specify quali   ed or
unquali   ed scalar type and the operand shall have scalar type."

So, I am pretty sure you are right : An alias is allowed.

> Comeau C++ in strict mode follows the C++ standard in this regard, as
> does the development version of g++ (which will become 4.2), though
> older versions of g++ follow the C standard.  During testing of the
> new version in Debian, we found that this change broke a C++ program
> that uses the OpenAL library, one of whose headers used a type alias
> for void in a function parameter list.
>
I tried Comeau C99 online, in strict mode, and it seems to interpret it
as incorrect C too:
typedef void VOID;
void f(VOID)
{
}
int main()
{

f();
}
> Given that this special case only exists in C++ for compatibility with
> C, it seems to be a defect in the standard that it is defined slightly
> differently.
>
Yes, it looks like a defect in the C++ standard.
The obvious resolution would be to adopt the C99 rule, since that stuff
is only here for backward compatibility... So, it's better being fully
compatible.

What I don't like, is the fact that C99 seems to interpret differently
the C99 standard from us (Me, and you).


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Sat, 22 Apr 2006 23:28:58 CST
Raw View
Ben Hutchings wrote:
> [ Note: Forwarded to C++ Committee. -sdc ]
>
> The standard says this about the void parameter list:
>
> "The parameter list (void) is equivalent to the empty parameter list."
> (8.3.5 [dcl.fct] paragraph 2)
>
The C++ standard seems to be pretty clear here : type aliases are
forbidden.

> The C99 standard apparently says something slightly different, though
> I'm afraid I'm quoting from a draft here:
>
> "The special case of an unnamed parameter of type void as the only
> item in the list specifies that the function has no parameters."
> (6.7.5.3 paragraph 10)
>
> If I understand these correctly, this means a C compiler must take
> type aliases into account before checking for the special case whereas
> a C++ compiler must not.
>
I read a bit the C99 standard, and reading 6.7.7 (Type definitions),
and searching whole text for "void type" seems to confirm that a
typedef for the void type, is a void type.
For example 6.5.4-2 (Cast operators) says that:
"Unless the type name speci   es a void type, the type name shall
specify quali   ed or
unquali   ed scalar type and the operand shall have scalar type."

So, I am pretty sure you are right : An alias is allowed.

> Comeau C++ in strict mode follows the C++ standard in this regard, as
> does the development version of g++ (which will become 4.2), though
> older versions of g++ follow the C standard.  During testing of the
> new version in Debian, we found that this change broke a C++ program
> that uses the OpenAL library, one of whose headers used a type alias
> for void in a function parameter list.
>
I tried Comeau C99 online, in strict mode, and it seems to interpret it
as incorrect C too:
typedef void VOID;
void f(VOID)
{
}
int main()
{

f();
}
> Given that this special case only exists in C++ for compatibility with
> C, it seems to be a defect in the standard that it is defined slightly
> differently.
>
Yes, it looks like a defect in the C++ standard.
The obvious resolution would be to adopt the C99 rule, since that stuff
is only here for backward compatibility... So, it's better being fully
compatible.

What I don't like, is the fact that Comeau seems to interpret
differently the C99 standard from us (Me, and you).


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]