Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #9326 > unrolled thread

which of these 3 casts would you prefer?

Started by"A" <a@a.a>
First post2011-08-25 23:58 +0200
Last post2011-08-26 07:30 -0700
Articles 20 on this page of 51 — 20 participants

Back to article view | Back to comp.lang.c++


Contents

  which of these 3 casts would you prefer? "A" <a@a.a> - 2011-08-25 23:58 +0200
    Re: which of these 3 casts would you prefer? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-25 16:19 -0700
    Re: which of these 3 casts would you prefer? Robert Wessel <robertwessel2@yahoo.com> - 2011-08-25 18:59 -0500
    Re: which of these 3 casts would you prefer? "Alf P. Steinbach" <alf.p.steinbach:usenet@gmail.com> - 2011-08-26 08:02 +0200
    Re: which of these 3 casts would you prefer? "Duga Chernobyl" <duga_c3@gmx.com> - 2011-08-26 10:05 +0200
      Re: which of these 3 casts would you prefer? "A" <a@a.a> - 2011-08-26 14:40 +0200
        Re: which of these 3 casts would you prefer? Leigh Johnston <leigh@i42.co.uk> - 2011-08-26 13:59 +0100
        Re: which of these 3 casts would you prefer? "Duga Chernobyl" <duga_c3@gmx.com> - 2011-08-26 15:19 +0200
          Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-26 21:27 +0000
            Re: which of these 3 casts would you prefer? "Alf P. Steinbach" <alf.p.steinbach:usenet@gmail.com> - 2011-08-27 01:28 +0200
            Re: which of these 3 casts would you prefer? "Duga Chernobyl" <duga_c3@gmx.com> - 2011-08-27 10:23 +0200
              Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-27 12:10 +0000
            Re: which of these 3 casts would you prefer? RaZiel <raziel_206_@hotmail.com> - 2011-08-27 21:55 +0200
            Re: which of these 3 casts would you prefer? Miles Bader <miles@gnu.org> - 2011-09-01 08:03 +0900
              Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-31 23:11 -0700
              Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-01 19:34 +0000
                Re: which of these 3 casts would you prefer? Joshua Maurice <joshuamaurice@gmail.com> - 2011-09-01 15:37 -0700
                  Re: which of these 3 casts would you prefer? gwowen <gwowen@gmail.com> - 2011-09-02 00:30 -0700
                    Re: which of these 3 casts would you prefer? Miles Bader <miles@gnu.org> - 2011-09-03 18:26 +0900
        Re: which of these 3 casts would you prefer? Edek <edek.pienkowski@gmail.com> - 2011-08-26 15:29 +0200
        Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-27 09:35 -0700
          Re: which of these 3 casts would you prefer? Juha Nieminen <nospam@thanks.invalid> - 2011-08-27 18:38 +0000
            Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-27 12:32 -0700
              Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-27 14:51 -0700
                Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-29 14:10 +0000
                  Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-30 07:23 -0700
              Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-29 11:32 +0000
            Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-27 14:37 -0700
              Re: which of these 3 casts would you prefer? Ian Collins <ian-news@hotmail.com> - 2011-08-28 10:06 +1200
                Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-27 15:27 -0700
                  Re: which of these 3 casts would you prefer? Ian Collins <ian-news@hotmail.com> - 2011-08-28 10:47 +1200
                  Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-27 15:42 -0700
                  Re: which of these 3 casts would you prefer? Nobody <nobody@nowhere.com> - 2011-08-28 04:15 +0100
              Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-27 15:52 -0700
                Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-28 01:54 -0700
                  Re: which of these 3 casts would you prefer? Keith H Duggar <duggar@alum.mit.edu> - 2011-09-04 19:16 -0700
              Re: which of these 3 casts would you prefer? Juha Nieminen <nospam@thanks.invalid> - 2011-08-29 18:16 +0000
                Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-29 16:35 -0700
                  Re: which of these 3 casts would you prefer? Nobody <nobody@nowhere.com> - 2011-08-30 04:13 +0100
                  Re: which of these 3 casts would you prefer? Juha Nieminen <nospam@thanks.invalid> - 2011-08-30 06:03 +0000
                Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-30 07:12 -0700
                  Re: which of these 3 casts would you prefer? Juha Nieminen <nospam@thanks.invalid> - 2011-08-31 06:16 +0000
                    Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-09-01 03:05 -0700
                      Re: which of these 3 casts would you prefer? Juha Nieminen <nospam@thanks.invalid> - 2011-09-01 07:00 +0000
                        Re: which of these 3 casts would you prefer? BGB <cr88192@hotmail.com> - 2011-08-31 13:21 -0700
            Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-28 19:30 +0000
        Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-27 12:19 -0700
          Re: which of these 3 casts would you prefer? Dombo <dombo@disposable.invalid> - 2011-08-28 12:08 +0200
          Re: which of these 3 casts would you prefer? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-08-28 19:44 +0000
            Re: which of these 3 casts would you prefer? Noah Roberts <roberts.noah@gmail.com> - 2011-08-28 13:41 -0700
      Re: which of these 3 casts would you prefer? Anand Hariharan <mailto.anand.hariharan@gmail.com> - 2011-08-26 07:30 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#9361

FromBGB <cr88192@hotmail.com>
Date2011-08-27 09:35 -0700
Message-ID<j3b6me$eof$1@news.albasani.net>
In reply to#9333
On 8/26/2011 5:40 AM, A wrote:
> I do not understand though reluctance to use C style casts.
>
> They can cast to reinterpret_cast but they also try out the weaker cast
> before. It is just automatic way to do what you would do manually - first
> try const_cast, then static_cast and finally reinterpret_cast... yes, it can
> use reinterpret_cast but you would have to use it anyway in a particular
> case where you really need it.
>
> So what's wrong with little automation, providing that you know what you are
> doing with casts?
>

unlike the others here, I don't take much issue with C style casts.


then again, I am also primarily a C programmer (for various reasons), 
and most of the C++ code I have written has been in a C-like style 
(usually either because for some reason I needed C++, such as 
interfacing with a C++ only library, or because there is C++/CLI but not 
a C/CLI, ...).


one can also argue that function overloading and operator overloading 
are nifty, but rarely have I found this to be a big issue (one can 
typically sort-of make due with using short macro names to redirect to 
longer operator function names or similar, and with the convention of 
using short suffixes to function names to indicate the argument types or 
similar...).


it is not that I don't know about OOP or whatever, just that:
what I usually want done can be done "well enough" in C explicitly using 
structs and vtables (so C can still do OOP, sort of);
in other cases, I am using a language like C# or Java, or my own 
scripting language (vaguely ActionScript-like);
it often just so happens to be a bit easier to do multi-direction 
cross-language interfacing in C than in C++.


not that my case likely represents a normal development process though, 
and if one is doing pure C++ (or pure C++ for application code with C 
mostly in back-end libraries), then the comments made by others here 
make more sense.

also, FWIW, my own scripting language doesn't have C-like casts (mostly 
for syntactic reasons though, namely syntactic ambiguity), but instead 
splits them into multiple casts indicated by a keyword ("x as type", "x 
as! type", ...).


or such...

[toc] | [prev] | [next] | [standalone]


#9362

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-08-27 18:38 +0000
Message-ID<4e5939a5$0$3061$7b1e8fa0@news.nbl.fi>
In reply to#9361
BGB <cr88192@hotmail.com> wrote:
> one can also argue that function overloading and operator overloading 
> are nifty, but rarely have I found this to be a big issue (one can 
> typically sort-of make due with using short macro names to redirect to 
> longer operator function names or similar, and with the convention of 
> using short suffixes to function names to indicate the argument types or 
> similar...).

  The reason why function and operator overloading is important is not
because it's "handy" or "convenient" or anything like that. It's because
it's *necessary* for generic programming. It's what allows you to do
things like this:

    template<typename T>
    T foo(T value)
    {
        std::cout << "The input value was " << value << std::endl;
        return std::cos(value);
    }

  The above code would be impossible without function and operator
overloading. For example in C you have cos(), cosf() and cosl(), and
you just can't write a macro that would call the proper function based
on the type of the parameter. In C++ you have just different versions
of std::cos(), and the proper version will be automatically called
depending on the type of parameter.

  (You could write *three* macros with different names, but now you have
not only triplicated your code, you have made it impossible to call
the macro from other macros without triplicating those too, so the
triplication becomes contagious. Also, it doesn't allow the user to use
a custom user-defined type.)

  Likewise it's what allows the std::cout above to work properly.

  This is something the most C programmers don't understand. They are
not to blame, though, because many C++ programmers don't know this either
(or have never thought about it).

> it is not that I don't know about OOP or whatever, just that:
> what I usually want done can be done "well enough" in C explicitly using 
> structs and vtables (so C can still do OOP, sort of);

  The major problem in C is not the lack of dynamic binding. It's the
lack of RAII and templates. (And, to some extent, exceptions.)

[toc] | [prev] | [next] | [standalone]


#9364

FromNoah Roberts <roberts.noah@gmail.com>
Date2011-08-27 12:32 -0700
Message-ID<bd93b3a0-bbb6-4bcf-beb2-d69c6cc21c66@n19g2000prh.googlegroups.com>
In reply to#9362
On Aug 27, 11:38 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> BGB <cr88...@hotmail.com> wrote:
> > one can also argue that function overloading and operator overloading
> > are nifty, but rarely have I found this to be a big issue (one can
> > typically sort-of make due with using short macro names to redirect to
> > longer operator function names or similar, and with the convention of
> > using short suffixes to function names to indicate the argument types or
> > similar...).
>
>   The reason why function and operator overloading is important is not
> because it's "handy" or "convenient" or anything like that. It's because
> it's *necessary* for generic programming. It's what allows you to do
> things like this:
>
>     template<typename T>
>     T foo(T value)
>     {
>         std::cout << "The input value was " << value << std::endl;
>         return std::cos(value);
>     }

You don't even need to be doing this to run into the lack of function
overloading as a great annoyance.  I recently started working in a
project where the lead architect insists it's in C (there are a bunch
of other things that are more frustrating to me about it than that,
but whatever).  I've found the necessity to think of obscure names to
make sure to avoid any naming conflicts is a serious quandry.  For
example, in writing a generic stack, vector, or managed string class
(I have no problem with C OOP, it can be elegant in its own way) you
have many functions that have a related concept but of course are very
different in implementation.  You could use polymorphism to get by,
but what if you don't want to use polymorphism?  You're quite stuck
having to name functions like isEmpty to things like
isNamespaceStackEmpty and isNamespaceStringEmpty, and you're always
going to be worried that somewhere someone else is naming their stack
or vector functions the same thing.

Luckily the project code is quite small and this isn't anything but a
minor annoyance, but I can't imagine having to deal with it on a
larger scale.  In C++ these things just work themselves out and they
work themselves out quite well in a very direct manner that is easy to
detect errors.  There are rules like ADL and more complex rules when
possible overloads are templates, but they're actually not that hard
to remember especially for the gain you get from them.  Honestly this
issue has bugged me more than any lack of operator overloads, etc...

[toc] | [prev] | [next] | [standalone]


#9373

FromBGB <cr88192@hotmail.com>
Date2011-08-27 14:51 -0700
Message-ID<j3bp5p$m1c$1@news.albasani.net>
In reply to#9364
On 8/27/2011 12:32 PM, Noah Roberts wrote:
> On Aug 27, 11:38 am, Juha Nieminen<nos...@thanks.invalid>  wrote:
>> BGB<cr88...@hotmail.com>  wrote:
>>> one can also argue that function overloading and operator overloading
>>> are nifty, but rarely have I found this to be a big issue (one can
>>> typically sort-of make due with using short macro names to redirect to
>>> longer operator function names or similar, and with the convention of
>>> using short suffixes to function names to indicate the argument types or
>>> similar...).
>>
>>    The reason why function and operator overloading is important is not
>> because it's "handy" or "convenient" or anything like that. It's because
>> it's *necessary* for generic programming. It's what allows you to do
>> things like this:
>>
>>      template<typename T>
>>      T foo(T value)
>>      {
>>          std::cout<<  "The input value was "<<  value<<  std::endl;
>>          return std::cos(value);
>>      }
>
> You don't even need to be doing this to run into the lack of function
> overloading as a great annoyance.  I recently started working in a
> project where the lead architect insists it's in C (there are a bunch
> of other things that are more frustrating to me about it than that,
> but whatever).  I've found the necessity to think of obscure names to
> make sure to avoid any naming conflicts is a serious quandry.  For
> example, in writing a generic stack, vector, or managed string class
> (I have no problem with C OOP, it can be elegant in its own way) you
> have many functions that have a related concept but of course are very
> different in implementation.  You could use polymorphism to get by,
> but what if you don't want to use polymorphism?  You're quite stuck
> having to name functions like isEmpty to things like
> isNamespaceStackEmpty and isNamespaceStringEmpty, and you're always
> going to be worried that somewhere someone else is naming their stack
> or vector functions the same thing.
>

this is a problem of naming conventions...

for example, a fairly common naming convention is something like:
library_subsystem_function.

so, a person would name things more like:
int MyFooLib_MyContainerStuff_IsHashEmpty()
{
	...
}

with "MyFooLib" generally being something a bit more accurate.

now, provided people don't create libraries with the same names, then 
there is not a clash.

another convention is:
prefixSomeFunctionName();

where prefix is the short name of a library.
however, this needs to be used a little more sparingly, as the chances 
of a 2 to 4 letter prefix or similar clashing are far higher than with a 
longer name.


> Luckily the project code is quite small and this isn't anything but a
> minor annoyance, but I can't imagine having to deal with it on a
> larger scale.  In C++ these things just work themselves out and they
> work themselves out quite well in a very direct manner that is easy to
> detect errors.  There are rules like ADL and more complex rules when
> possible overloads are templates, but they're actually not that hard
> to remember especially for the gain you get from them.  Honestly this
> issue has bugged me more than any lack of operator overloads, etc...


with a good naming convention, then code scales well into the Mloc range 
without too many issues on this front.

granted, yes, not everyone agrees as to the ideal naming conventions, 
and a lot of older code has had problems here (often due to people not 
properly qualifying names, simply describing the action or type in a 
terse form, and then running into naming conflicts).

[toc] | [prev] | [next] | [standalone]


#9437

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-08-29 14:10 +0000
Message-ID<slrnj5n7fb.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#9373
On Sat, 2011-08-27, BGB wrote:
> On 8/27/2011 12:32 PM, Noah Roberts wrote:
>> On Aug 27, 11:38 am, Juha Nieminen<nos...@thanks.invalid>  wrote:
>>> BGB<cr88...@hotmail.com>  wrote:
>>>> one can also argue that function overloading and operator overloading
>>>> are nifty, but rarely have I found this to be a big issue (one can
>>>> typically sort-of make due with using short macro names to redirect to
>>>> longer operator function names or similar, and with the convention of
>>>> using short suffixes to function names to indicate the argument types or
>>>> similar...).
>>>
>>>    The reason why function and operator overloading is important is not
>>> because it's "handy" or "convenient" or anything like that. It's because
>>> it's *necessary* for generic programming. It's what allows you to do
>>> things like this:
>>>
>>>      template<typename T>
>>>      T foo(T value)
>>>      {
>>>          std::cout<<  "The input value was "<<  value<<  std::endl;
>>>          return std::cos(value);
>>>      }
>>
>> You don't even need to be doing this to run into the lack of function
>> overloading as a great annoyance.  I recently started working in a
>> project where the lead architect insists it's in C (there are a bunch
>> of other things that are more frustrating to me about it than that,
>> but whatever).  I've found the necessity to think of obscure names to
>> make sure to avoid any naming conflicts is a serious quandry.  For
>> example, in writing a generic stack, vector, or managed string class
>> (I have no problem with C OOP, it can be elegant in its own way) you
>> have many functions that have a related concept but of course are very
>> different in implementation.  You could use polymorphism to get by,
>> but what if you don't want to use polymorphism?  You're quite stuck
>> having to name functions like isEmpty to things like
>> isNamespaceStackEmpty and isNamespaceStringEmpty, and you're always
>> going to be worried that somewhere someone else is naming their stack
>> or vector functions the same thing.
>>
>
> this is a problem of naming conventions...
>
> for example, a fairly common naming convention is something like:
> library_subsystem_function.
>
> so, a person would name things more like:
> int MyFooLib_MyContainerStuff_IsHashEmpty()
> {
> 	...
> }
>
> with "MyFooLib" generally being something a bit more accurate.
>
> now, provided people don't create libraries with the same names, then 
> there is not a clash.

Imagine a piece of code, perhaps a function with a loop, which uses
plenty of functions like that. Start with C++ names, e.g. empty(), and
then replace them with long, unique names like
MyFooLib_MyContainerStuff_IsHashEmpty().  I think you will agree that
readability decreases sharply.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#9482

FromBGB <cr88192@hotmail.com>
Date2011-08-30 07:23 -0700
Message-ID<j3is2q$u5a$1@news.albasani.net>
In reply to#9437
On 8/29/2011 7:10 AM, Jorgen Grahn wrote:
> On Sat, 2011-08-27, BGB wrote:
>> On 8/27/2011 12:32 PM, Noah Roberts wrote:
>>> On Aug 27, 11:38 am, Juha Nieminen<nos...@thanks.invalid>   wrote:
>>>> BGB<cr88...@hotmail.com>   wrote:
>>>>> one can also argue that function overloading and operator overloading
>>>>> are nifty, but rarely have I found this to be a big issue (one can
>>>>> typically sort-of make due with using short macro names to redirect to
>>>>> longer operator function names or similar, and with the convention of
>>>>> using short suffixes to function names to indicate the argument types or
>>>>> similar...).
>>>>
>>>>     The reason why function and operator overloading is important is not
>>>> because it's "handy" or "convenient" or anything like that. It's because
>>>> it's *necessary* for generic programming. It's what allows you to do
>>>> things like this:
>>>>
>>>>       template<typename T>
>>>>       T foo(T value)
>>>>       {
>>>>           std::cout<<   "The input value was"<<   value<<   std::endl;
>>>>           return std::cos(value);
>>>>       }
>>>
>>> You don't even need to be doing this to run into the lack of function
>>> overloading as a great annoyance.  I recently started working in a
>>> project where the lead architect insists it's in C (there are a bunch
>>> of other things that are more frustrating to me about it than that,
>>> but whatever).  I've found the necessity to think of obscure names to
>>> make sure to avoid any naming conflicts is a serious quandry.  For
>>> example, in writing a generic stack, vector, or managed string class
>>> (I have no problem with C OOP, it can be elegant in its own way) you
>>> have many functions that have a related concept but of course are very
>>> different in implementation.  You could use polymorphism to get by,
>>> but what if you don't want to use polymorphism?  You're quite stuck
>>> having to name functions like isEmpty to things like
>>> isNamespaceStackEmpty and isNamespaceStringEmpty, and you're always
>>> going to be worried that somewhere someone else is naming their stack
>>> or vector functions the same thing.
>>>
>>
>> this is a problem of naming conventions...
>>
>> for example, a fairly common naming convention is something like:
>> library_subsystem_function.
>>
>> so, a person would name things more like:
>> int MyFooLib_MyContainerStuff_IsHashEmpty()
>> {
>> 	...
>> }
>>
>> with "MyFooLib" generally being something a bit more accurate.
>>
>> now, provided people don't create libraries with the same names, then
>> there is not a clash.
>
> Imagine a piece of code, perhaps a function with a loop, which uses
> plenty of functions like that. Start with C++ names, e.g. empty(), and
> then replace them with long, unique names like
> MyFooLib_MyContainerStuff_IsHashEmpty().  I think you will agree that
> readability decreases sharply.
>

whether or not it is pretty is a much lesser concern though than whether 
or not one is liable to have a name clash.


but, anyways, the point is mostly that C can be used in ways which don't 
lead to people falling on their faces, but not necessarily that C is a 
programmer-friendly language.

but, much like anything, one uses something some, internalizes all of 
its little rituals, conventions, and practices, and then it is no longer 
an issue.


much like a manual vs automatic transmission...
with an automatic, one doesn't have to worry about gears and up/down 
shifting, ...
whereas a person who is used to manual will just automatically hit the 
clutch, shift, release clutch, and continue on their way, generally 
without thinking much about it (because it all becomes 
reflex/muscle-memory/...).


or such...

[toc] | [prev] | [next] | [standalone]


#9434

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-08-29 11:32 +0000
Message-ID<slrnj5mu5u.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#9364
On Sat, 2011-08-27, Noah Roberts wrote:
> On Aug 27, 11:38 am, Juha Nieminen <nos...@thanks.invalid> wrote:
...
>>   The reason why function and operator overloading is important is not
>> because it's "handy" or "convenient" or anything like that. It's because
>> it's *necessary* for generic programming. It's what allows you to do
>> things like this:
>>
>>     template<typename T>
>>     T foo(T value)
>>     {
>>         std::cout << "The input value was " << value << std::endl;
>>         return std::cos(value);
>>     }
>
> You don't even need to be doing this to run into the lack of function
> overloading as a great annoyance.  I recently started working in a
> project where the lead architect insists it's in C (there are a bunch
> of other things that are more frustrating to me about it than that,
> but whatever).  I've found the necessity to think of obscure names to
> make sure to avoid any naming conflicts is a serious quandry.

Damn, you already said what I posted in <slrnj5l5qe.gtj.grahn+nntp@
frailea.sa.invalid> one day later.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#9372

FromBGB <cr88192@hotmail.com>
Date2011-08-27 14:37 -0700
Message-ID<j3bobh$kkf$1@news.albasani.net>
In reply to#9362
On 8/27/2011 11:38 AM, Juha Nieminen wrote:
> BGB<cr88192@hotmail.com>  wrote:
>> one can also argue that function overloading and operator overloading
>> are nifty, but rarely have I found this to be a big issue (one can
>> typically sort-of make due with using short macro names to redirect to
>> longer operator function names or similar, and with the convention of
>> using short suffixes to function names to indicate the argument types or
>> similar...).
>
>    The reason why function and operator overloading is important is not
> because it's "handy" or "convenient" or anything like that. It's because
> it's *necessary* for generic programming. It's what allows you to do
> things like this:
>
>      template<typename T>
>      T foo(T value)
>      {
>          std::cout<<  "The input value was "<<  value<<  std::endl;
>          return std::cos(value);
>      }
>
>    The above code would be impossible without function and operator
> overloading. For example in C you have cos(), cosf() and cosl(), and
> you just can't write a macro that would call the proper function based
> on the type of the parameter. In C++ you have just different versions
> of std::cos(), and the proper version will be automatically called
> depending on the type of parameter.
>
>    (You could write *three* macros with different names, but now you have
> not only triplicated your code, you have made it impossible to call
> the macro from other macros without triplicating those too, so the
> triplication becomes contagious. Also, it doesn't allow the user to use
> a custom user-defined type.)
>
>    Likewise it's what allows the std::cout above to work properly.
>
>    This is something the most C programmers don't understand. They are
> not to blame, though, because many C++ programmers don't know this either
> (or have never thought about it).
>

yes, fair enough. C does not do this...

however, it could be argued that *not* having to write duplicated code 
in this case is what is nifty/convinient/...


as well, there is another partial way around this problem:
one can implement a dynamic type-system, and then use wrapping and 
run-time type-checking for a lot of this. it is a tradeoff (performance 
is worse, ...), but it works.

another variant is to use JVM-like "signature strings" which are used 
alongside any data, with a lot of the type-specific behavior being 
handled by character-driven logic.

both are fairly useful in implementing VMs, and have different merits 
and drawbacks. in my case I end up using both strategies in different 
situations (well, along with having parts of the typesystem being 
essentially driven by queries to a hierarchical database system...).


otherwise, I had developed a much fancier macro preprocessor that can be 
used with C (using it to implement such combinatorial/"generic" code was 
one thing I had used it for), but I didn't really use it much for a few 
reasons:
cases where it was needed were fairly rare;
it is likely that in cases where one feels the need for such a 
mechanism, they are likely "doing it wrong" anyways;
it is kind of a build hassle to run code though an additional 
preprocessor prior to running it through the main compiler.

worst case, one will copy/paste the logic a few times and specialize it 
for each type or situation involved (or keep it in memory, and write out 
a specialized version if/when a need for it pops up, so for example 
people have the logic for linked-lists/hashes/quicksort/... generally 
memorized).


>> it is not that I don't know about OOP or whatever, just that:
>> what I usually want done can be done "well enough" in C explicitly using
>> structs and vtables (so C can still do OOP, sort of);
>
>    The major problem in C is not the lack of dynamic binding. It's the
> lack of RAII and templates. (And, to some extent, exceptions.)

RAII normally only really deals with cases which can be dealt with 
manually though (apart from exceptions, which also don't exist in C, and 
things like longjmp are rarely used).

also, several other major languages, such as Java and C#, also lack RAII 
(with exceptions, this behavior is handled by the use of a "finally" 
clause).

[toc] | [prev] | [next] | [standalone]


#9375

FromIan Collins <ian-news@hotmail.com>
Date2011-08-28 10:06 +1200
Message-ID<9bt839FopsU3@mid.individual.net>
In reply to#9372
On 08/28/11 09:37 AM, BGB wrote:
> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>>
>>     The major problem in C is not the lack of dynamic binding. It's the
>> lack of RAII and templates. (And, to some extent, exceptions.)
>
> RAII normally only really deals with cases which can be dealt with
> manually though (apart from exceptions, which also don't exist in C, and
> things like longjmp are rarely used).

The beauty of RAII is you don't have to implement it manually!  This 
eliminates a whole class of common programming errors.

> also, several other major languages, such as Java and C#, also lack RAII
> (with exceptions, this behavior is handled by the use of a "finally"
> clause).

Yet another manual kludge..

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#9376

FromBGB <cr88192@hotmail.com>
Date2011-08-27 15:27 -0700
Message-ID<j3brak$q7n$1@news.albasani.net>
In reply to#9375
On 8/27/2011 3:06 PM, Ian Collins wrote:
> On 08/28/11 09:37 AM, BGB wrote:
>> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>>>
>>> The major problem in C is not the lack of dynamic binding. It's the
>>> lack of RAII and templates. (And, to some extent, exceptions.)
>>
>> RAII normally only really deals with cases which can be dealt with
>> manually though (apart from exceptions, which also don't exist in C, and
>> things like longjmp are rarely used).
>
> The beauty of RAII is you don't have to implement it manually! This
> eliminates a whole class of common programming errors.
>

yep, but this is still more of a convenience feature, rather than a 
fundamental limitation.


it is not really too much different from using OpenGL and remembering to 
always have a matching "glEnd();" for every "glBegin();", or a 
"glPopMatrix();" for every "glPushMatrix();".

if one messes up on these sorts of things in OpenGL, things will turn 
ugly...



>> also, several other major languages, such as Java and C#, also lack RAII
>> (with exceptions, this behavior is handled by the use of a "finally"
>> clause).
>
> Yet another manual kludge..
>

well, it can be seen this way...

I am not claiming here that C is perfect or equally programmer-friendly 
to C++ or anything, but rather there may be other bigger concerns, and 
that conveniences are not "essential".


in my own script language, there are value-types / structs, which will 
call the destructor any time they go out of scope (internally, in the 
VM, classes and structs are more-or-less equivalent, only that some 
extra behaviors exist in the struct case, namely that it is copied 
rather than passed by reference, and its destructor is called whenever 
it goes out of scope).

but, anyways, they could potentially be used to do something analogous 
to RAII (albeit more limited due to the present lack of 
copy-constructors or similar).


now, why do they exist?... because these sorts of things are actually 
sort of useful (personally, I find the "everything is a 
pass-by-reference object" mentality of Java to be a little annoying, 
among other things...).

[toc] | [prev] | [next] | [standalone]


#9378

FromIan Collins <ian-news@hotmail.com>
Date2011-08-28 10:47 +1200
Message-ID<9btaggFopsU4@mid.individual.net>
In reply to#9376
On 08/28/11 10:27 AM, BGB wrote:
> On 8/27/2011 3:06 PM, Ian Collins wrote:
>> On 08/28/11 09:37 AM, BGB wrote:
>>> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>>>>
>>>> The major problem in C is not the lack of dynamic binding. It's the
>>>> lack of RAII and templates. (And, to some extent, exceptions.)
>>>
>>> RAII normally only really deals with cases which can be dealt with
>>> manually though (apart from exceptions, which also don't exist in C, and
>>> things like longjmp are rarely used).
>>
>> The beauty of RAII is you don't have to implement it manually! This
>> eliminates a whole class of common programming errors.
>
> yep, but this is still more of a convenience feature, rather than a
> fundamental limitation.

It is a fundamental feature in the sense that it allows automated 
resource management.  Automated resource management leads to safer, 
cleaner, code.  It also removes the single, all be it feeble, excuse for 
using goto which has to be a good thing!

> it is not really too much different from using OpenGL and remembering to
> always have a matching "glEnd();" for every "glBegin();", or a
> "glPopMatrix();" for every "glPushMatrix();".
>
> if one messes up on these sorts of things in OpenGL, things will turn
> ugly...

Exactly.  With RAII, you eliminate the chance of things turning ugly.

>>> also, several other major languages, such as Java and C#, also lack RAII
>>> (with exceptions, this behavior is handled by the use of a "finally"
>>> clause).
>>
>> Yet another manual kludge..
>>
>
> well, it can be seen this way...

How else can you see it?  Missing a finally (or leaving a release out of 
one) is just as bad as forgetting a free in C.

> I am not claiming here that C is perfect or equally programmer-friendly
> to C++ or anything, but rather there may be other bigger concerns, and
> that conveniences are not "essential".

No language feature is "essential".  We can program in machine code if 
we choose.  Most of us don't write machine code these days (although I 
have to admit I did enjoy it back in the day!) because we have 
programming languages that directly support safer and more advanced 
idioms.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#9381

FromNoah Roberts <roberts.noah@gmail.com>
Date2011-08-27 15:42 -0700
Message-ID<abe1c25e-c39a-48c1-ba1b-f46817f36bf7@x11g2000prb.googlegroups.com>
In reply to#9376
On Aug 27, 3:27 pm, BGB <cr88...@hotmail.com> wrote:
> On 8/27/2011 3:06 PM, Ian Collins wrote:
>
> > On 08/28/11 09:37 AM, BGB wrote:
> >> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>
> >>> The major problem in C is not the lack of dynamic binding. It's the
> >>> lack of RAII and templates. (And, to some extent, exceptions.)
>
> >> RAII normally only really deals with cases which can be dealt with
> >> manually though (apart from exceptions, which also don't exist in C, and
> >> things like longjmp are rarely used).
>
> > The beauty of RAII is you don't have to implement it manually! This
> > eliminates a whole class of common programming errors.
>
> yep, but this is still more of a convenience feature, rather than a
> fundamental limitation.

That's getting pretty silly isn't it?  Both languages are Turing
complete, either one CAN do anything the other does just as you CAN do
anything in brainfuck that you could have done in C or C++.  The
difference being of course, how much time do you want to waste writing
something that another language offers to you for free.

>
> it is not really too much different from using OpenGL and remembering to
> always have a matching "glEnd();" for every "glBegin();", or a
> "glPopMatrix();" for every "glPushMatrix();".
>
> if one messes up on these sorts of things in OpenGL, things will turn
> ugly...

In C++ you can use RAII for that sort of thing.  With C, again, you
have to manually track it all and do everything the hard way.

[toc] | [prev] | [next] | [standalone]


#9386

FromNobody <nobody@nowhere.com>
Date2011-08-28 04:15 +0100
Message-ID<pan.2011.08.28.03.15.43.846000@nowhere.com>
In reply to#9376
On Sat, 27 Aug 2011 15:27:46 -0700, BGB wrote:

>> The beauty of RAII is you don't have to implement it manually! This
>> eliminates a whole class of common programming errors.
> 
> yep, but this is still more of a convenience feature, rather than a 
> fundamental limitation.

You can't take this argument much further before you start arguing that
everything about high-level languages is a convenience, because you could
do the same thing in assembler.

> it is not really too much different from using OpenGL and remembering to 
> always have a matching "glEnd();" for every "glBegin();", or a 
> "glPopMatrix();" for every "glPushMatrix();".

That's slightly different, as you normally care about the precise location
of the glEnd/glPopMatrix/etc. With destruction, you normally only care
that the object gets destroyed "soon" after its last use. You can force
destruction by using an extra block, but this is seldom considered
necessary.

[toc] | [prev] | [next] | [standalone]


#9380

FromNoah Roberts <roberts.noah@gmail.com>
Date2011-08-27 15:52 -0700
Message-ID<b934e362-1d86-450d-83f9-0c40bb29d04e@x14g2000prn.googlegroups.com>
In reply to#9372
On Aug 27, 2:37 pm, BGB <cr88...@hotmail.com> wrote:
> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>
>
>
>
>
>
>
>
>
> > BGB<cr88...@hotmail.com>  wrote:
> >> one can also argue that function overloading and operator overloading
> >> are nifty, but rarely have I found this to be a big issue (one can
> >> typically sort-of make due with using short macro names to redirect to
> >> longer operator function names or similar, and with the convention of
> >> using short suffixes to function names to indicate the argument types or
> >> similar...).
>
> >    The reason why function and operator overloading is important is not
> > because it's "handy" or "convenient" or anything like that. It's because
> > it's *necessary* for generic programming. It's what allows you to do
> > things like this:
>
> >      template<typename T>
> >      T foo(T value)
> >      {
> >          std::cout<<  "The input value was "<<  value<<  std::endl;
> >          return std::cos(value);
> >      }
>
> >    The above code would be impossible without function and operator
> > overloading. For example in C you have cos(), cosf() and cosl(), and
> > you just can't write a macro that would call the proper function based
> > on the type of the parameter. In C++ you have just different versions
> > of std::cos(), and the proper version will be automatically called
> > depending on the type of parameter.
>
> >    (You could write *three* macros with different names, but now you have
> > not only triplicated your code, you have made it impossible to call
> > the macro from other macros without triplicating those too, so the
> > triplication becomes contagious. Also, it doesn't allow the user to use
> > a custom user-defined type.)
>
> >    Likewise it's what allows the std::cout above to work properly.
>
> >    This is something the most C programmers don't understand. They are
> > not to blame, though, because many C++ programmers don't know this either
> > (or have never thought about it).
>
> yes, fair enough. C does not do this...
>
> however, it could be argued that *not* having to write duplicated code
> in this case is what is nifty/convinient/...

You seem to be saying that function overloading is not necessary for
generic programming because you don't have to use generic
programming.  Same can be said of any paradigm.

Tell me, why are you not writing all your code in assembler?
Certainly it is possible to do so.

>
> as well, there is another partial way around this problem:
> one can implement a dynamic type-system, and then use wrapping and
> run-time type-checking for a lot of this. it is a tradeoff (performance
> is worse, ...), but it works.
>

In C++ we call this polymorphism and it is another built in feature we
don't have to develop on our own.

[toc] | [prev] | [next] | [standalone]


#9394

FromBGB <cr88192@hotmail.com>
Date2011-08-28 01:54 -0700
Message-ID<j3d02e$gkr$1@news.albasani.net>
In reply to#9380
On 8/27/2011 3:52 PM, Noah Roberts wrote:
> On Aug 27, 2:37 pm, BGB<cr88...@hotmail.com>  wrote:
>> On 8/27/2011 11:38 AM, Juha Nieminen wrote:
>>
>>
>>> BGB<cr88...@hotmail.com>    wrote:
>>>> one can also argue that function overloading and operator overloading
>>>> are nifty, but rarely have I found this to be a big issue (one can
>>>> typically sort-of make due with using short macro names to redirect to
>>>> longer operator function names or similar, and with the convention of
>>>> using short suffixes to function names to indicate the argument types or
>>>> similar...).
>>
>>>     The reason why function and operator overloading is important is not
>>> because it's "handy" or "convenient" or anything like that. It's because
>>> it's *necessary* for generic programming. It's what allows you to do
>>> things like this:
>>
>>>       template<typename T>
>>>       T foo(T value)
>>>       {
>>>           std::cout<<    "The input value was "<<    value<<    std::endl;
>>>           return std::cos(value);
>>>       }
>>
>>>     The above code would be impossible without function and operator
>>> overloading. For example in C you have cos(), cosf() and cosl(), and
>>> you just can't write a macro that would call the proper function based
>>> on the type of the parameter. In C++ you have just different versions
>>> of std::cos(), and the proper version will be automatically called
>>> depending on the type of parameter.
>>
>>>     (You could write *three* macros with different names, but now you have
>>> not only triplicated your code, you have made it impossible to call
>>> the macro from other macros without triplicating those too, so the
>>> triplication becomes contagious. Also, it doesn't allow the user to use
>>> a custom user-defined type.)
>>
>>>     Likewise it's what allows the std::cout above to work properly.
>>
>>>     This is something the most C programmers don't understand. They are
>>> not to blame, though, because many C++ programmers don't know this either
>>> (or have never thought about it).
>>
>> yes, fair enough. C does not do this...
>>
>> however, it could be argued that *not* having to write duplicated code
>> in this case is what is nifty/convinient/...
>
> You seem to be saying that function overloading is not necessary for
> generic programming because you don't have to use generic
> programming.  Same can be said of any paradigm.
>

potentially, then one can find the minimum core of a language which can 
still express the desired set of functionality.


> Tell me, why are you not writing all your code in assembler?
> Certainly it is possible to do so.
>

because then I would have to port all that assembler between the various 
targets platforms...

I have enough assembler in the project already, much of it mirrored 
between different CPU/OS configurations.

so, ASM is generally used sparingly, such as when a given feature can't 
be readily implemented directly in a higher-level form.

granted, many nifty parts of the codebase are written in ASM (mostly x86 
and x86-64, but there is some ARM related stuff around as well).

technically, the program involves self-modifying code as well.

a nifty use of ASM is to be able to implement reflection mechanisms such 
as a generic apply, and also to implement features such as closures 
which mimic ordinary function pointers, ...


however, ASM can also be a little verbose at times.


>>
>> as well, there is another partial way around this problem:
>> one can implement a dynamic type-system, and then use wrapping and
>> run-time type-checking for a lot of this. it is a tradeoff (performance
>> is worse, ...), but it works.
>>
>
> In C++ we call this polymorphism and it is another built in feature we
> don't have to develop on our own.

yes, people so much commenting "well I don't have to do X manually", but 
what really is the big deal?...


but, anyways, about as soon as one wants to write an interpreter they 
will have to implement a lot of this stuff anyways regardless of the 
choice of language.

then one may also find themselves faced with such issues as to how to 
effectively integrate the interpreter with the host language, ...

having a simpler host language, with a simpler ABI, ... can have its 
advantages here.

[toc] | [prev] | [next] | [standalone]


#9744

FromKeith H Duggar <duggar@alum.mit.edu>
Date2011-09-04 19:16 -0700
Message-ID<04f3f05d-baa7-4326-835d-99e34e48eda0@q12g2000yqd.googlegroups.com>
In reply to#9394
On Aug 28, 4:54 am, BGB <cr88...@hotmail.com> wrote:
> On 8/27/2011 3:52 PM, Noah Roberts wrote:
> > Tell me, why are you not writing all your code in assembler?
> > Certainly it is possible to do so.
>
> because then I would have to port all that assembler between the various
> targets platforms...

"however, it could be argued that *not* having to write duplicated
code in this case is what is nifty/convinient/..." C is just nifty
syntax sugar over assembly.

;-)

> however, ASM can also be a little verbose at times.

Compared to MyFooLib_MyContainerStuff_IsHashEmpty?

> yes, people so much commenting "well I don't have to do X
> manually", but what really is the big deal?...

*sigh* How is it that you do you appreciate the basic value of
standardization and/or automation? Or are you just playing dumb
for the sake of tedium?

KHD

[toc] | [prev] | [next] | [standalone]


#9441

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-08-29 18:16 +0000
Message-ID<4e5bd772$0$2869$7b1e8fa0@news.nbl.fi>
In reply to#9372
BGB <cr88192@hotmail.com> wrote:
>>    The major problem in C is not the lack of dynamic binding. It's the
>> lack of RAII and templates. (And, to some extent, exceptions.)
> 
> RAII normally only really deals with cases which can be dealt with 
> manually though (apart from exceptions, which also don't exist in C, and 
> things like longjmp are rarely used).

  You write as if the lack of RAII was only a minor inconvenience. I don't
agree with that.

  One of the major problems with that lack, which means that resources
have to be managed manually, is that this management burden is "contagious".
With that I mean that if you have a type which needs to be destroyed
manually, that requirement is transferred to any other type that wants
to use that type as a member. (In other words, if you have eg. a struct
that needs to be constructed and destructed by explicitly calling some
functions, if you want to use that struct as a member of another struct,
you need to write equivalent construction/destruction functions for *that*
struct too, and the need to manually call them is "inherited" by that
struct. And so on. It can become quite complicated and burdensome.)

  It also makes generic programming a lot more difficult. If you make,
for example, a generic container, you have no way of knowing whether
the elements need to be properly destroyed before freeing them or not.
If you want your container to support such elements, you have to offer
some kind of construction/destruction paradigm, which can be inconvenient,
and in the case of elements that don't need it, needless overhead.

> also, several other major languages, such as Java and C#, also lack RAII 
> (with exceptions, this behavior is handled by the use of a "finally" 
> clause).

  This is actually a problem in Java because if you have to manage any
resource other than memory, you run into the problem of having to free
the resource manually (at least if the resource should be freed as soon
as possible; the finalizer mechanism in Java doesn't guarantee when
destructors will be called, or even that they will be called at all).

  The 'finally' block only handles a subset of cases that RAII does, and
it's nevertheless more burdensome because you have to implement it
manually. (At least it's safer than anything in C, which is a plus.)

[toc] | [prev] | [next] | [standalone]


#9456

FromNoah Roberts <roberts.noah@gmail.com>
Date2011-08-29 16:35 -0700
Message-ID<fd93de54-4921-4f74-9a6b-70fc8d79e078@r40g2000prf.googlegroups.com>
In reply to#9441
On Aug 29, 11:16 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> BGB <cr88...@hotmail.com> wrote:
> >>    The major problem in C is not the lack of dynamic binding. It's the
> >> lack of RAII and templates. (And, to some extent, exceptions.)
>
> > RAII normally only really deals with cases which can be dealt with
> > manually though (apart from exceptions, which also don't exist in C, and
> > things like longjmp are rarely used).
>
>   You write as if the lack of RAII was only a minor inconvenience. I don't
> agree with that.

Yeah, how did I miss that gem?  I agree with you.

Exceptions are by far the only place where RAII is useful.  They are
but one way for a function to exit early.  Any and all times that you
have a resource or more to allocate and can leave a function early due
to error conditions is an important place to be using RAII.  Without
you're stuck making sure you manually release those parts you were so
far able to acquire.

Yeah, it can be said that it's "just" a convenience but I have to say
it's a pretty damn big one.  Sort of like having a car is only a
"convenience" when you need to travel 100 miles.

[toc] | [prev] | [next] | [standalone]


#9457

FromNobody <nobody@nowhere.com>
Date2011-08-30 04:13 +0100
Message-ID<pan.2011.08.30.03.13.05.940000@nowhere.com>
In reply to#9456
On Mon, 29 Aug 2011 16:35:26 -0700, Noah Roberts wrote:

>>   You write as if the lack of RAII was only a minor inconvenience. I don't
>> agree with that.
> 
> Yeah, how did I miss that gem?  I agree with you.
> 
> Exceptions are by far the only place where RAII is useful.

I presume you mean "far from" rather than "by far"?

> They are
> but one way for a function to exit early.  Any and all times that you
> have a resource or more to allocate and can leave a function early due
> to error conditions is an important place to be using RAII.

Not just functions, but any block. Aside from return: break, continue and
goto can cause automatic variables to leave scope.

[toc] | [prev] | [next] | [standalone]


#9463

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-08-30 06:03 +0000
Message-ID<4e5c7d2c$0$3099$7b1e8fa0@news.nbl.fi>
In reply to#9456
Noah Roberts <roberts.noah@gmail.com> wrote:
> Exceptions are by far the only place where RAII is useful.  They are
> but one way for a function to exit early.  Any and all times that you
> have a resource or more to allocate and can leave a function early due
> to error conditions is an important place to be using RAII.  Without
> you're stuck making sure you manually release those parts you were so
> far able to acquire.
> 
> Yeah, it can be said that it's "just" a convenience but I have to say
> it's a pretty damn big one.  Sort of like having a car is only a
> "convenience" when you need to travel 100 miles.

  And code blocks are not the only situation where RAII comes into play.
It also does so when types (which have to be constructed and destroyed
properly) are members of other types, or inside data containers. With
RAII the parent type doesn't need to worry about the member object: It
will be automatically constructed and destroyed approperiately, without
the parent type having to do anything special about it (with the only
exception being if the member object needs some constructor parameters,
which of course makes sense).

  This even in the case of a specific type using another specific type
as a member. It becomes even more important with generic programming.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web