Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #9326 > unrolled thread
| Started by | "A" <a@a.a> |
|---|---|
| First post | 2011-08-25 23:58 +0200 |
| Last post | 2011-08-26 07:30 -0700 |
| Articles | 20 on this page of 51 — 20 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Noah Roberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2011-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Noah Roberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | Noah Roberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2011-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]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Keith H Duggar <duggar@alum.mit.edu> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Noah Roberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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