Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #12146 > unrolled thread
| Started by | ittium <ittium@gmail.com> |
|---|---|
| First post | 2011-12-08 12:01 +0530 |
| Last post | 2011-12-09 03:05 -0800 |
| Articles | 8 — 5 participants |
Back to article view | Back to comp.lang.c++
Argument type of function and safe types and types, arguments can handle safely ittium <ittium@gmail.com> - 2011-12-08 12:01 +0530
Re: Argument type of function and safe types and types, arguments can handle safely Paavo Helde <myfirstname@osa.pri.ee> - 2011-12-08 02:17 -0600
Re: Argument type of function and safe types and types, arguments can handle safely 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-08 00:31 -0800
Re: Argument type of function and safe types and types, arguments can handle safely ittium <ittium@gmail.com> - 2011-12-08 16:57 +0530
Re: Argument type of function and safe types and types, arguments can handle safely Paavo Helde <myfirstname@osa.pri.ee> - 2011-12-08 12:32 -0600
Re: Argument type of function and safe types and types, arguments can handle safely Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-12-08 20:00 +0000
Re: Argument type of function and safe types and types, arguments can handle safely Paavo Helde <myfirstname@osa.pri.ee> - 2011-12-08 14:30 -0600
Re: Argument type of function and safe types and types, arguments can handle safely Goran <goran.pusic@gmail.com> - 2011-12-09 03:05 -0800
| From | ittium <ittium@gmail.com> |
|---|---|
| Date | 2011-12-08 12:01 +0530 |
| Subject | Argument type of function and safe types and types, arguments can handle safely |
| Message-ID | <jbplnk$qrf$1@dont-email.me> |
Groups, I have few doubts regarding argument type of function and types, arguments can handle safely. I know these issues have been discussed at multiple places on internet. I wanted to see the big picture and needed opinion of C++ gurus When you pass by value - Copy constructor is called (except for basic data type like int, float). you can pass the **same type variable** only When you pass by reference - A reference will be intialized with pass value. you can pass **non-const same type or derived type** (passing a constant type will return in error) When you pass by constant reference you can pass **const/non-const of same type or derived type**. When you pass by pointer - pointer is assigned to passed value you can pass **same type of derived type**. Cases written above are safe conversion (no casting is needed). **C++ compiler will not allow any other conversion **. You can still use casting for not allowed cases. My doubts are - Have I captured all the cases or there are some more cases (I will appreciate a link to a small reference) -What casts are safe e.g in case of pass by value casting from short to int seems perfectly safe. (I will appreciate a link to any document explaining safe casting) thanks Ittium
[toc] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-12-08 02:17 -0600 |
| Message-ID | <Xns9FB568AC8EB33myfirstnameosapriee@216.196.109.131> |
| In reply to | #12146 |
ittium <ittium@gmail.com> wrote in news:jbplnk$qrf$1@dont-email.me: > Groups, > I have few doubts regarding argument type of function and types, > arguments can handle safely. It depends on what you mean by "safely". It may mean a lot of things, starting from "the code is so clear, robust and self-contained that it will not need any change or refactoring in the next 30 years" up to "the argument content can be accessed safely from other threads while the first thread is sitting in this function call, but only in physically read-only mode, and until a given semaphore elsewhere in the code has not been signalled". > I know these issues have been discussed at > multiple places on internet. I wanted to see the big picture The big picture is that the language provides a multitude of different ways to pass information, each with their own trade-offs, and the programmer is obliged to select the correct one according to the actual needs. And the devil is in the details as always. > > When you pass by value - Copy constructor is called (except for basic > data type like int, float). Copy ctor calls may be elided by the compiler, even when it can cause visible side-effects. > you can pass the **same type variable** only > Nope, you can pass derived type objects as well, but they get sliced down. Not sure if this qualifies as "safely". > When you pass by reference - A reference will be intialized with pass > value. you can pass **non-const same type or derived type** (passing a > constant type will return in error) > > When you pass by constant reference you can pass **const/non-const of > same type or derived type**. A const reference can also bind to a temporary if direct binding is not possible, and there is a suitable conversion available. Some of the nastiest bugs I have seen were due to a (buggy) compiler binding a non- const reference to an automatically created temporary. > > When you pass by pointer - pointer is assigned to passed value you can > pass **same type of derived type**. You ignore the const-non-const topic here, which for pointers is both simpler (no converted temporaries) and more complex (pointers themselves can be const or non-const, which turns especially tricky with several levels of indirection). > > Cases written above are safe conversion (no casting is needed). **C++ > compiler will not allow any other conversion **. You can still use > casting for not allowed cases. Only if this does not make you code invalid ;) > > My doubts are > - Have I captured all the cases or there are some more cases (I will > appreciate a link to a small reference) There certainly are; string literals and rvalue references pop in mind first. > > -What casts are safe e.g in case of pass by value casting from short to > int seems perfectly safe. (I will appreciate a link to any document > explaining safe casting) Much more tiny evil details. Short-to-int does not require a cast, at least not when signedness is the same. Otherwise, each cast has its own rules. Static_cast validness depends on the value you are casting. Const_cast validness may depend on a lot of things. Reinterpret_cast validness depends on the implementation details of the particular compiler and platform combination. Cheers Paavo
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2011-12-08 00:31 -0800 |
| Message-ID | <24498188.511.1323333110485.JavaMail.geo-discussion-forums@prgg19> |
| In reply to | #12150 |
On Thursday, December 8, 2011 4:17:22 PM UTC+8, Paavo Helde wrote: > ittium <itt...@gmail.com> wrote in news:jbplnk$qrf$1...@dont-email.me: > > > Groups, > > I have few doubts regarding argument type of function and types, > > arguments can handle safely. > > It depends on what you mean by "safely". It may mean a lot of things, > starting from "the code is so clear, robust and self-contained that it > will not need any change or refactoring in the next 30 years" up to "the > argument content can be accessed safely from other threads while the > first thread is sitting in this function call, but only in physically > read-only mode, and until a given semaphore elsewhere in the code has not > been signalled". > > > I know these issues have been discussed at > > multiple places on internet. I wanted to see the big picture > > The big picture is that the language provides a multitude of different > ways to pass information, each with their own trade-offs, and the > programmer is obliged to select the correct one according to the actual > needs. And the devil is in the details as always. > > > > > When you pass by value - Copy constructor is called (except for basic > > data type like int, float). > > Copy ctor calls may be elided by the compiler, even when it can cause > visible side-effects. > > > you can pass the **same type variable** only > > > > Nope, you can pass derived type objects as well, but they get sliced > down. Not sure if this qualifies as "safely". > > A const reference can also bind to a temporary if direct binding is not > possible, and there is a suitable conversion available. Some of the > nastiest bugs I have seen were due to a (buggy) compiler binding a non- > const reference to an automatically created temporary. > A small structure, say 16 to 128 bytes in the stack, is not big and can be accessed efficiently than a big chunk of a multi-dimensional array that sits on a heap classified in L2 or the lousy slow DRAM banks. This assumes that the stack is accessed in L0 or L1 in the run time. No deep stack probing and fat chunks in the heap is the reason to copy by values of 16 to 128 bytes. > > When you pass by pointer - pointer is assigned to passed value you can > > pass **same type of derived type**. > > You ignore the const-non-const topic here, which for pointers is both > simpler (no converted temporaries) and more complex (pointers themselves > can be const or non-const, which turns especially tricky with several > levels of indirection). > > > > > Cases written above are safe conversion (no casting is needed). **C++ > > compiler will not allow any other conversion **. You can still use > > casting for not allowed cases. > > Only if this does not make you code invalid ;) > > > > > My doubts are > > - Have I captured all the cases or there are some more cases (I will > > appreciate a link to a small reference) > > There certainly are; string literals and rvalue references pop in mind > first. > > > > > -What casts are safe e.g in case of pass by value casting from short to > > int seems perfectly safe. (I will appreciate a link to any document > > explaining safe casting) > > Much more tiny evil details. Short-to-int does not require a cast, at > least not when signedness is the same. Otherwise, each cast has its own > rules. Static_cast validness depends on the value you are casting. > Const_cast validness may depend on a lot of things. Reinterpret_cast > validness depends on the implementation details of the particular > compiler and platform combination. > > Cheers > Paavo
[toc] | [prev] | [next] | [standalone]
| From | ittium <ittium@gmail.com> |
|---|---|
| Date | 2011-12-08 16:57 +0530 |
| Message-ID | <jbq722$5dl$1@dont-email.me> |
| In reply to | #12150 |
On 12/8/2011 1:47 PM, Paavo Helde wrote: > ittium<ittium@gmail.com> wrote in news:jbplnk$qrf$1@dont-email.me: > >> Groups, >> I have few doubts regarding argument type of function and types, >> arguments can handle safely. > > It depends on what you mean by "safely". It may mean a lot of things, > starting from "the code is so clear, robust and self-contained that it > will not need any change or refactoring in the next 30 years" up to "the > argument content can be accessed safely from other threads while the > first thread is sitting in this function call, but only in physically > read-only mode, and until a given semaphore elsewhere in the code has not > been signalled". Paavo, first thanks for the detailed response, for this discussion, by safely I mean the type of arguments that can be passed to a argument without any typecasting. > >> I know these issues have been discussed at >> multiple places on internet. I wanted to see the big picture > > The big picture is that the language provides a multitude of different > ways to pass information, each with their own trade-offs, and the > programmer is obliged to select the correct one according to the actual > needs. And the devil is in the details as always. > >> >> When you pass by value - Copy constructor is called (except for basic >> data type like int, float). > > Copy ctor calls may be elided by the compiler, even when it can cause > visible side-effects. > >> you can pass the **same type variable** only >> > > Nope, you can pass derived type objects as well, but they get sliced > down. Not sure if this qualifies as "safely". Thanks for pointing this out, yes I missed it. Atleast in the context of this discussion, it is safe. > >> When you pass by reference - A reference will be intialized with pass >> value. you can pass **non-const same type or derived type** (passing a >> constant type will return in error) >> >> When you pass by constant reference you can pass **const/non-const of >> same type or derived type**. > > A const reference can also bind to a temporary if direct binding is not > possible, and there is a suitable conversion available. Some of the > nastiest bugs I have seen were due to a (buggy) compiler binding a non- > const reference to an automatically created temporary. > >> >> When you pass by pointer - pointer is assigned to passed value you can >> pass **same type of derived type**. > > You ignore the const-non-const topic here, which for pointers is both > simpler (no converted temporaries) and more complex (pointers themselves > can be const or non-const, which turns especially tricky with several > levels of indirection). > yes I missed this topic, pointer to constant can accept pointer to non-constant and but other way is not allowed. You are right, Pointer itself can be constant. There will be many interesting cases when you consider both value and the pointer to be const/non-const. >> >> Cases written above are safe conversion (no casting is needed). **C++ >> compiler will not allow any other conversion **. You can still use >> casting for not allowed cases. > > Only if this does not make you code invalid ;) Absolutely, casting is like telling the compiler, I am more intelligent than you and should be avoided. > >> >> My doubts are >> - Have I captured all the cases or there are some more cases (I will >> appreciate a link to a small reference) > > There certainly are; string literals and rvalue references pop in mind > first. yes, If I have any doubt about these string literals/ravlue ask in the group if I have doubts. I Request to all the group members who are reading this post to add more cases if, I have missed any. >> >> -What casts are safe e.g in case of pass by value casting from short to >> int seems perfectly safe. (I will appreciate a link to any document >> explaining safe casting) > > Much more tiny evil details. Short-to-int does not require a cast, at > least not when signedness is the same. I am actually interested in all those cases where cast is not needed. I will appreciate a reference to some link that covers all the cases where casting is not required. >Otherwise, each cast has its own > rules. Static_cast validness depends on the value you are casting. > Const_cast validness may depend on a lot of things. Reinterpret_cast > validness depends on the implementation details of the particular > compiler and platform combination. Absolutely, while writing code, I always try to avoid the casts, I have asked this question so that I can take better decisions about (class/non-class) method signatures. > > Cheers > Paavo
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-12-08 12:32 -0600 |
| Message-ID | <Xns9FB5D0ED87FCEmyfirstnameosapriee@216.196.109.131> |
| In reply to | #12160 |
ittium <ittium@gmail.com> wrote in news:jbq722$5dl$1@dont-email.me: > > Absolutely, > while writing code, I always try to avoid the casts, I have asked this > question so that I can take better decisions about (class/non-class) > method signatures. Well, this is much simpler question, although it depends somewhat on whether speed issues are important or not. The main goal is to keep the interfaces simple, both from the implementation and usage point of view, but preferring usage simplicity. This means for example that usage should not normally require any casts, if casts are required by any reason they should be encapsulated in the implementation. The better "callability" does depend to some extent on the function signature, though logical simplicity and good names are far more important. Some rules related to signatures might be: - use const wherever possible (except top-level const which does not carry information) - use the same types as typical client code - avoid premature optimizations (which would make usage more difficult) - avoid unusual signatures - use return value for passing information out of the function, instead of modifying the arguments - signal errors with exceptions instead of error codes - avoid hidden or global state inside (free) functions These rules a bit contradictory in C++ because of a design flaw in the core (C) language: "const" should actually be the default and passing mutable parameters should require extra keywords instead. Currently writing conceptually simplest signatures means spraying 'const' all over the place. There is a common habit to pass class objects by const reference instead of value. This might be considered a premature optimization and a complication of the signature, but as it does not usually affect the usage in any way I believe this would be OK. Actually, as this is so widespread then passing by value would actually go against the rule "avoid unusual signatures". If speed is important, these rules will be slightly modified and the interfaces may become more complex. hth Paavo
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-12-08 20:00 +0000 |
| Message-ID | <slrnje25qf.q8l.grahn+nntp@frailea.sa.invalid> |
| In reply to | #12195 |
On Thu, 2011-12-08, Paavo Helde wrote: ... > The better "callability" does depend to some extent on the function > signature, though logical simplicity and good names are far more > important. Some rules related to signatures might be: > > - use const wherever possible (except top-level const which does not > carry information) > - use the same types as typical client code > - avoid premature optimizations (which would make usage more difficult) > - avoid unusual signatures > - use return value for passing information out of the function, instead > of modifying the arguments > - signal errors with exceptions instead of error codes I don't think this is a good idea, if it's an error which is likely to happen and needs to be handled locally. > - avoid hidden or global state inside (free) functions But I agree with the rest. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-12-08 14:30 -0600 |
| Message-ID | <Xns9FB5E4F49833Fmyfirstnameosapriee@216.196.109.131> |
| In reply to | #12209 |
Jorgen Grahn <grahn+nntp@snipabacken.se> wrote in news:slrnje25qf.q8l.grahn+nntp@frailea.sa.invalid: > On Thu, 2011-12-08, Paavo Helde wrote: >> - signal errors with exceptions instead of error codes > > I don't think this is a good idea, if it's an error which is likely to > happen and needs to be handled locally. Yes, if something is handled locally, it is simpler to use an error code than to set up a try-catch block. And if something is not handled locally, then it is simpler to use a try-catch block upstream than to check for error codes everywhere. And if speed is important, one must take into account that exception throwing might be quite expensive operation so one may have to use error codes or equivalent even for non-local handling if the "error" may appear often. Trade-offs as usual. Cheers Paavo
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-12-09 03:05 -0800 |
| Message-ID | <eadd78b8-5ebe-439c-87da-313426eccad0@f5g2000yqg.googlegroups.com> |
| In reply to | #12146 |
On Dec 8, 7:31 am, ittium <itt...@gmail.com> wrote: > Groups, > I have few doubts regarding argument type of function and types, > arguments can handle safely. I know these issues have been discussed at > multiple places on internet. I wanted to see the big picture and needed > opinion of C++ gurus > > When you pass by value - Copy constructor is called (except for basic > data type like int, float). I believe that it's better not to think like that. "basic" data types are copied just as any other. > you can pass the **same type variable** only You can e.g. pass a smaller integral type (say, short) where bigger is needed. You can also pass derived class instance where base is needed, but you'll suffer from "object slicing". That might, or might not, matter (it usually does). > When you pass by reference - A reference will be intialized with pass > value. you can pass **non-const same type or derived type** (passing a > constant type will return in error) Yes. Pass-by-ref is used when you want to change the parameter. > > When you pass by constant reference you can pass **const/non-const of > same type or derived type**. Yes. Purpose of this: to "design" through code and with the compiler's help what is being changed where, all while avoiding copying a lot of data around. (Pass by value designs the same thing, but suffers from a performance hit when parameters are big or otherwise expensive to copy). > When you pass by pointer - pointer is assigned to passed value you can > pass **same type of derived type**. Yes. Good C++ style is IMO to You pas by pointer to say: "here's a reference to something, but it's __optional__ (it might be null). There's little reason to use pointer parameters otherwise. > Cases written above are safe conversion (no casting is needed). **C++ > compiler will not allow any other conversion **. You can still use > casting for not allowed cases. > > My doubts are > - Have I captured all the cases or there are some more cases (I will > appreciate a link to a small reference) > > -What casts are safe e.g in case of pass by value casting from short to > int seems perfectly safe. (I will appreciate a link to any document > explaining safe casting) Don't have a link, but... Pretty much none is safe. You have to ensure, through code, that values are "convertible". In my mind, a cast is a design error, especially between numbers. So that should be fixed, and casts will go away ;-). Goran.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web