Argument type of function and safe types and types, arguments canhandle safely

I

ittium

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
 
8

88888 Dihedral

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".


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.


Copy ctor calls may be elided by the compiler, even when it can cause
visible side-effects.


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.
 
I

ittium

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.
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.


Copy ctor calls may be elided by the compiler, even when it can cause
visible side-effects.


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.
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.


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.
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.
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.
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.
 
J

Jorgen Grahn

.
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
 
G

Goran

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top