POV-Ray : Newsgroups : povray.off-topic : Computer language quirks Server Time
30 Jul 2024 00:18:59 EDT (-0400)
  Computer language quirks (Message 24 to 33 of 33)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: clipka
Subject: Re: Computer language quirks
Date: 13 May 2011 10:43:59
Message: <4dcd43af$1@news.povray.org>
Am 13.05.2011 09:44, schrieb Zeger Knaepen:

> I suppose it wouldn't work if "bar" really had a return-value.

Indeed, but you could still cast it to void:

     return (void)bar(...);


Post a reply to this message

From: clipka
Subject: Re: Computer language quirks
Date: 13 May 2011 10:46:24
Message: <4dcd4440$1@news.povray.org>
Am 11.05.2011 22:17, schrieb Darren New:
> On 5/11/2011 12:57, Warp wrote:
>> compiles and runs just fine.
>
> Huh. I wonder if that's just a GCC thing or whether that's actually in
> the standard. I just *actually* tried it with C# and I get "since XYZ
> returns void, the return statement may not be followed by an expression."


The C language standard is pretty clear about this; quoting from 
ISO/IEC 9899:TC2:

"6.8.6.4 The return statement
Constraints
1  A return statement with an expression shall not appear in a function 
whose return type is void. [...]"


The C++ standard, however, explicitly allows for such a construction; 
quoting from some 2005 working draft:

"6.6.3 The return statement [stmt.return]
[...]
3  A return statement with an expression of type “cv void” can be used 
only in functions with a return type of cv void; [...]."

("cv" being shorthand for "an arbitrary set of cv-qualifiers, i.e., one 
of {const }, {volatile }, {const, volatile}, or the empty set")


Not of Java though; quoting from "The Java(TM) Language Specification, 
Third Edition":

"8.4.7 Method Body
[...]
If a method is declared void, then its body must not contain any return
statement (§14.17) that has an Expression."


So it appears that C++ is about the only member of the C-style language 
family allowing for such a construct per specification.


Post a reply to this message

From: Invisible
Subject: Re: Computer language quirks
Date: 13 May 2011 10:51:35
Message: <4dcd4577$1@news.povray.org>
>> Huh. I wonder if that's just a GCC thing or whether that's actually in
>> the standard. I just *actually* tried it with C# and I get "since XYZ
>> returns void, the return statement may not be followed by an expression."
>
>
> The C language standard is pretty clear about this; quoting from ISO/IEC
> 9899:TC2:
>
> "6.8.6.4 The return statement
> Constraints
> 1 A return statement with an expression shall not appear in a function
> whose return type is void. [...]"
>
>
> The C++ standard, however, explicitly allows for such a construction;
> quoting from some 2005 working draft:
>
> "6.6.3 The return statement [stmt.return]
> [...]
> 3 A return statement with an expression of type “cv void” can be used
> only in functions with a return type of cv void; [...]."
>
> ("cv" being shorthand for "an arbitrary set of cv-qualifiers, i.e., one
> of {const }, {volatile }, {const, volatile}, or the empty set")
>
>
> Not of Java though; quoting from "The Java(TM) Language Specification,
> Third Edition":
>
> "8.4.7 Method Body
> [...]
> If a method is declared void, then its body must not contain any return
> statement (§14.17) that has an Expression."
>
>
> So it appears that C++ is about the only member of the C-style language
> family allowing for such a construct per specification.

Now that's what a call thorough research! O_O


Post a reply to this message

From: Darren New
Subject: Re: Computer language quirks
Date: 13 May 2011 12:51:16
Message: <4dcd6184$1@news.povray.org>
On 5/13/2011 0:44, Zeger Knaepen wrote:
> the function "bar" doesn't return anything, so if "foo" returns the
> return-value of "bar", it also doesn't return anything.

And that's exactly why I started this thread. The syntax makes that 
distinction, whereas I thought it shouldn't. Turns out that C++ at least 
really doesn't make that decision.

Altho given that a simple "return;" from a function declared as returning an 
int in C doesn't even raise a warning in gcc, I suspect it's at least as 
much the traditional sloppiness of C in terms of parameter passing as it is 
something intentionally designed into the spec.  ("return 28;" from a void 
function gives a warning but not an error.)

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Darren New
Subject: Re: Computer language quirks
Date: 13 May 2011 12:54:09
Message: <4dcd6231$1@news.povray.org>
On 5/13/2011 7:46, clipka wrote:
> So it appears that C++ is about the only member of the C-style language
> family allowing for such a construct per specification.

Thanks for looking all that up!   (I'll look up the C# if anyone cares. :-)

I suspect that was put in when templates and overloading and stuff made it 
make sense.

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Warp
Subject: Re: Computer language quirks
Date: 14 May 2011 03:40:37
Message: <4dce31f5@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> I suspect that was put in when templates and overloading and stuff made it 
> make sense.

  I get the feeling that, indeed, templates "demanded" a lot of relaxing of
the rules, which could have been much stricter (especially compared to C),
so that templated code would not break as easily if you changed between
types.

  For example, in C the only way to make an explicit cast is using the
syntax "(type) variable". However, C++ added the possibility of writing
such casts as "type(variable)". This allows for 'type' to not only be a
basic type, but also a class (in which case it would be a constructor
call).

  Moreover (something that many C++ programmers don't realize), C++ allows
the syntax "(type) variable" even for class types (in which case it's
*still* a constructor call). Basically "(type) variable" and "type(variable)"
are more or less identical expressions in C++. About the only practical
situation where this may come handy is in templated code.

  Overloading operators is useful in non-templated code as well, although
it becomes more or less syntactic sugar there. It's most useful in templated
code because it, once again, allows for the same code to handle basic types
and classes. It is, for example, what allows STL containers to handle both
types of elements. (For example std::set and std::map require for the
elements to be assignable, and comparable using the comparison operator <.
Since you can overload operator < for classes, this means that you can use
both internal types, such as ints, and classes, such as std::string, with
the same std::set or std::map.)

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: Computer language quirks
Date: 14 May 2011 12:34:57
Message: <4dceaf31$1@news.povray.org>
On 5/14/2011 0:40, Warp wrote:
>    For example, in C the only way to make an explicit cast is using the
> syntax "(type) variable". However, C++ added the possibility of writing
> such casts as "type(variable)". This allows for 'type' to not only be a
> basic type, but also a class (in which case it would be a constructor
> call).

That's cool. I'm still not sure whether to like C++ or hate it. ;-)

So what's the static_cast<...> bit all about, then? Is that just something 
easy to grep for, or does it have different semantics than a regular cast?

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

From: Warp
Subject: Re: Computer language quirks
Date: 15 May 2011 04:00:04
Message: <4dcf8804@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> On 5/14/2011 0:40, Warp wrote:
> >    For example, in C the only way to make an explicit cast is using the
> > syntax "(type) variable". However, C++ added the possibility of writing
> > such casts as "type(variable)". This allows for 'type' to not only be a
> > basic type, but also a class (in which case it would be a constructor
> > call).

> That's cool. I'm still not sure whether to like C++ or hate it. ;-)

> So what's the static_cast<...> bit all about, then? Is that just something 
> easy to grep for, or does it have different semantics than a regular cast?

  The C-style cast will cast from anything to anything else. Hence it's
not the safest thing in the world, as it's relatively easy to miscast and
have your program misbehave.

  static_cast will only work between compatible types. For example you can
cast an int to a char, a signed int to an unsigned int, classes to other
classes within their inheritance hierarchy, and so on. However, if you try
to static_cast between incompatible types, you will get a compiler error.
For example, you can't cast an int to a pointer, a const pointer to a
non-const one (even if the pointers are of the same type) or between classes
not in direct inheritance relationship.

  It is thus recommended to use static_cast instead of C style casts
whenever possible. Incidentally (but not surprisingly), if you use
static_cast to cast some variable to a class type, and that class has
a constructor that takes a value of that type, it will work. (It will
be the same as constructing the object with the regular syntax.) Supporting
the C style of casting exists more or less just for compatibility with C
code (which of course means that many C++ programmers are using it instead
of static_cast because it's shorter and more "convenient").

  To cast constness away between compatible types const_cast should be
used. (It's basically its only role.)

  To cast between incompatible types reinterpret_cast should be used.
(It assumes you know what you are doing.)

  reinterpret_cast should *not* be used to cast between pointers to objects
in the same inheritance hierarchy because it may forgo adjusting the pointer
offset which may be necessary in some situations.

-- 
                                                          - Warp


Post a reply to this message

From: clipka
Subject: Re: Computer language quirks
Date: 15 May 2011 04:36:26
Message: <4dcf908a$1@news.povray.org>
Am 14.05.2011 18:34, schrieb Darren New:
> On 5/14/2011 0:40, Warp wrote:
>> For example, in C the only way to make an explicit cast is using the
>> syntax "(type) variable". However, C++ added the possibility of writing
>> such casts as "type(variable)". This allows for 'type' to not only be a
>> basic type, but also a class (in which case it would be a constructor
>> call).
>
> That's cool. I'm still not sure whether to like C++ or hate it. ;-)
>
> So what's the static_cast<...> bit all about, then? Is that just
> something easy to grep for, or does it have different semantics than a
> regular cast?

"5.2.9 Static cast [expr.static.cast]
1  The result of the expression static_cast<T>(v) is the result of 
converting the expression v to type T. If T is a
reference type, the result is an lvalue; otherwise, the result is an 
rvalue. Types shall not be defined in a static_cast.
THE STATIC_CAST OPERATOR SHALL NOT CAST AWAY CONSTNESS (5.2.11)."
(emphasis added)

I.e. the static_cast of a const pointer remains a const pointer. It is 
therefore a good idea to always use static_cast instead of a classic 
cast, as it prevents accidental "stripping" of the const property; 
consider, for instance, the following code:

     void foo(int* x);
     void bar(void* x) {
         ...
         foo((int*)x);
         ...
     }

Now assume the code is refactored to use const qualifiers, but for some 
reason the cast in the call to foo() goes unnoticed:

     void foo(const int* x);
     void bar(const void* x) {
         ...
         foo((int*)x);
         ...
     }

Now assume a functionality change requires foo() to modify its parameter:

     void foo(int* x);
     void bar(const void* x) {
         ...
         foo((int*)x);
         ...
     }

The code still compiles, so it goes unnoticed that the function 
signature of bar() is now actually wrong.

If the original code author had used static_cast instead, the mistake 
would have been detected by the compiler, as the following code raises 
an error due to mismatching const qualifiers:

     void foo(int* x);
     void bar(const void* x) {
         ...
         foo(static_cast<int*>x);
         ...
     }


Post a reply to this message

From: Darren New
Subject: Re: Computer language quirks
Date: 15 May 2011 12:39:28
Message: <4dd001c0$1@news.povray.org>
On 5/15/2011 1:00, Warp wrote:
>    static_cast will only work between compatible types.

Ah, cool. Again, thanks for the info!

-- 
Darren New, San Diego CA, USA (PST)
   "Coding without comments is like
    driving without turn signals."


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.