473,395 Members | 1,956 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Small Issues on Convention


Let's say we have a function that returns the result of subtracting seven
from a given number. Would you write it as:

(A)

int SubtractSeven( int const x )
{
return x - 7;
}

(B)

int SubtractSeven( int x )
{
return x -= 7;
}

(C)

int SubtractSeven( int const& x )
{
return x - 7;
}
If we just wanted to "accomplish the task", without contemplating how fast
the code will run, or how much memory it will need, then I think the natural
choice is A. Do you agree with me?

If we consider efficiency, then we may think, "Why create that temporary? We
should just re-use the parameter variable.". This would make us lean toward
B.

Considering efficiency again, we may think to ourselves, "Why even create
that parameter variable? Let's just use the one we're supplied with (if
possible)". This would have some rationale to it (I'm open to correction
here) if we were dealing with an inline function... but if we're dealing
with an outline function, then we'd be playing around with pointers under
the hood, which, in the end, will be far less efficient than our original
example.

So... my aim is to draw up some conventions for the use of A, B and C.

Firstly, when do I use method C?

1: When I want to alter the supplied variable.

2: When I'm dealing with a user-defined type which consumes quite more
memory than an "int", or if the invokation of copy constructors would
involve considerable processing and dynamic allocation of memory.

Examples:

1:
void SubtractSevenFromGivenVariable(int &x)
{
x -= 7;
}

2:
unsigned CountAmountOfVowels( std::string const & str )
{
unsigned val;

//do stuff

return val;
}
Do you agree with me on when to use C?
If we had a small POD like the following:

struct XYCoord
{
unsigned x;
unsigned y;
};

then I would be probably not pass it by reference, and just pass it by
value. Do you agree with me here?

As for A and B... which shall it be?

I think that A is more natural, and is "the way things were supposed to be",
but I don't think we can deny the efficient reuse of a variable which we see
in B.
At the moment, I use the B method, although I'd be open to
advice/suggestions.

Do we have a const parameter and return a temporary? Or do we have a non-
const parameter, and return the result of subtracting seven from it?

-Tomás
Feb 20 '06 #1
10 1202
Tomás wrote:
Let's say we have a function that returns the result of subtracting seven
from a given number. Would you write it as:

(A)

int SubtractSeven( int const x )
{
return x - 7;
}
Why pass by const when passing by value?
(B)

int SubtractSeven( int x )
{
return x -= 7;
}
The passed parameter will not be modified.
(C)

int SubtractSeven( int const& x )
{
return x - 7;
}
The passed parameter will not be modified.
If we just wanted to "accomplish the task", without contemplating how fast
the code will run, or how much memory it will need, then I think the natural
choice is A. Do you agree with me?
No. The natural choice is:

int SubstractSeven(int x) {
return x - 7;
}
If we consider efficiency, then we may think, "Why create that temporary? We
should just re-use the parameter variable.". This would make us lean toward
B.
Nope without optimisation, b probably copies x at the call site, and in
the function and on the assignment after the call.
Considering efficiency again, we may think to ourselves, "Why even create
that parameter variable? Let's just use the one we're supplied with (if
possible)". This would have some rationale to it (I'm open to correction
here) if we were dealing with an inline function... but if we're dealing
with an outline function, then we'd be playing around with pointers under
the hood, which, in the end, will be far less efficient than our original
example.
What makes you think you'd be playing around with pointers under the hood?
So... my aim is to draw up some conventions for the use of A, B and C.

Firstly, when do I use method C?

1: When I want to alter the supplied variable.
But you don't, for a start it's const, and secondly you make a copy!
2: When I'm dealing with a user-defined type which consumes quite more
memory than an "int", or if the invokation of copy constructors would
involve considerable processing and dynamic allocation of memory.
Sorry, it's copied to modify it and return it anyway. But yes, pass by
const ref when it's not a native type and you don't need to modify it.
Examples:

1:
void SubtractSevenFromGivenVariable(int &x)
{
x -= 7;
}

2:
unsigned CountAmountOfVowels( std::string const & str )
{
unsigned val;

//do stuff

return val;
}
Do you agree with me on when to use C?
See above.
If we had a small POD like the following:

struct XYCoord
{
unsigned x;
unsigned y;
};

then I would be probably not pass it by reference, and just pass it by
value. Do you agree with me here?
I'd pass it by const ref, easier to optimise, and less maintenance
hassle if XYCoord becomes "more clever".
As for A and B... which shall it be?
Neither. See above.
I think that A is more natural, and is "the way things were supposed to be",
but I don't think we can deny the efficient reuse of a variable which we see
in B.
At the moment, I use the B method, although I'd be open to
advice/suggestions.

Do we have a const parameter and return a temporary? Or do we have a non-
const parameter, and return the result of subtracting seven from it?


For built in types you are not going to modify do this:
T builtIn(T t) { return t; }

For non built in types do this:
T notBuiltin(const T& t) { return t; }

If you want to modify the parameter do this:

T& modify(T& t) { return t; }

Don't concern yourself with whether a temporary can be reused, the
compiler will do all that for you.

Personally I would expect all 3 of your functions to end up the same
with only mild optimisation.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 20 '06 #2
A: int SubtractSeven( int const x )
B: int SubtractSeven( int x )
C: int SubtractSeven( int const& x )

Problem with A is, that A & B has exactly the same signature from
compiler point of view. If two things are the same usually it is better
to use only one. And usually B is used. A is a little bit too puristic.

Speaking about C, I think it should be total taboo even mention about
possibility to pass built in types by const reference or pointer to
const.

Feb 20 '06 #3
(A)

int SubtractSeven( int const x )
{
return x - 7; }
Why pass by const when passing by value?

I have a habit whereby I stick "const" everywhere that I can. Everywhere.

Everywhere.

It may or may not lead to optimisation by the compiler -- but it shall
certainly not have a detrimental effect.

(B)

int SubtractSeven( int x )
{
return x -= 7; }


The passed parameter will not be modified.

Correct. This is as intended.

(C)

int SubtractSeven( int const& x )
{
return x - 7; }


The passed parameter will not be modified.

Correct. This is as intended.
If we just wanted to "accomplish the task", without contemplating how
fast the code will run, or how much memory it will need, then I think
the natural choice is A. Do you agree with me?


No. The natural choice is:

int SubstractSeven(int x) {
return x - 7;
}

For you, yes. My own natural choice was to stick in "const".

What makes you think you'd be playing around with pointers under the
hood?
If the function is outline, then the machine code will work with pointers to
access the memory.

Please don't enter into a discussion which goes down the road of "A compiler
is free to implement features in whichever way it please, and doesn't have
to use pointers...".

So... my aim is to draw up some conventions for the use of A, B and C.

Firstly, when do I use method C?

1: When I want to alter the supplied variable.


But you don't, for a start it's const, and secondly you make a copy!


I was simply showing an alternative. I realise that I don't alter its value.

For built in types you are not going to modify do this:
T builtIn(T t) { return t; }

For non built in types do this:
T notBuiltin(const T& t) { return t; }

If you want to modify the parameter do this:

T& modify(T& t) { return t; }

Yes, but...

If we want to pass by value, thus not altering the variables value, we have
a choice of either:
(T is an intrinisc type:)

T SubtractSeven(T t) { return t -= 7; }

T SubtractSeven(T t) { return t - 7; }

Abiding by my "put const wherever I can rule", then the latter would be:

T SubtractSeven(T const t) { return t - 7; }
So when we're dealing with intrinsic types, do we go with:

(A) T SubtractSeven(T const t) { return t - 7; }
-or-
(B) T SubtractSeven(T t) { return t -= 7; }
-Tomás
Feb 20 '06 #4
LuB
A: int SubtractSeven( int const x )
B: int SubtractSeven( int x )
C: int SubtractSeven( int const& x )

Keep in mind that 'x' here is passed by value in A and B. Therefore,
they are semantically the same functions. It is impossible for A or B
to alter the original x parameter. The 'const' notation becomes
irrelevant. I'd actually consider it 'confusing' since it is well known
that x is passed by value. The next person to look at this code might
wonder what you were trying to accomplish ... maybe you left off '&' or
something ...

In addition, unless you are using an environment where sizeof(&int) !=
sizeof(int) .. I don't think you gain a performance edge by using C
since, passing and int by value or reference moves the same number of
bits ...

Hth,

-LutherB


Tomás wrote:
Let's say we have a function that returns the result of subtracting seven
from a given number. Would you write it as:

(A)

int SubtractSeven( int const x )
{
return x - 7;
}

(B)

int SubtractSeven( int x )
{
return x -= 7;
}

(C)

int SubtractSeven( int const& x )
{
return x - 7;
}
If we just wanted to "accomplish the task", without contemplating how fast
the code will run, or how much memory it will need, then I think the natural
choice is A. Do you agree with me?

If we consider efficiency, then we may think, "Why create that temporary?We
should just re-use the parameter variable.". This would make us lean toward
B.

Considering efficiency again, we may think to ourselves, "Why even create
that parameter variable? Let's just use the one we're supplied with (if
possible)". This would have some rationale to it (I'm open to correction
here) if we were dealing with an inline function... but if we're dealing
with an outline function, then we'd be playing around with pointers under
the hood, which, in the end, will be far less efficient than our original
example.

So... my aim is to draw up some conventions for the use of A, B and C.

Firstly, when do I use method C?

1: When I want to alter the supplied variable.

2: When I'm dealing with a user-defined type which consumes quite more
memory than an "int", or if the invokation of copy constructors would
involve considerable processing and dynamic allocation of memory.

Examples:

1:
void SubtractSevenFromGivenVariable(int &x)
{
x -= 7;
}

2:
unsigned CountAmountOfVowels( std::string const & str )
{
unsigned val;

//do stuff

return val;
}
Do you agree with me on when to use C?
If we had a small POD like the following:

struct XYCoord
{
unsigned x;
unsigned y;
};

then I would be probably not pass it by reference, and just pass it by
value. Do you agree with me here?

As for A and B... which shall it be?

I think that A is more natural, and is "the way things were supposed to be",
but I don't think we can deny the efficient reuse of a variable which we see
in B.
At the moment, I use the B method, although I'd be open to
advice/suggestions.

Do we have a const parameter and return a temporary? Or do we have a non-
const parameter, and return the result of subtracting seven from it?

-Tomás


Feb 20 '06 #5
Tomás wrote:
(A)

int SubtractSeven( int const x )
{
return x - 7; } Why pass by const when passing by value?

I have a habit whereby I stick "const" everywhere that I can. Everywhere.

Everywhere.

It may or may not lead to optimisation by the compiler -- but it shall
certainly not have a detrimental effect.


Not to the generated code, but readability may affected (one way or
another). Personally I would start to wonder why you had made it const
when it couldn't possibly be modified since it's passed by value. Then
I would wonder if you had intended it to be passed by reference.
If we just wanted to "accomplish the task", without contemplating how
fast the code will run, or how much memory it will need, then I think
the natural choice is A. Do you agree with me?

No. The natural choice is:

int SubstractSeven(int x) {
return x - 7;
}

For you, yes. My own natural choice was to stick in "const".


Then that's ok, but it doesn't actually gain you anything.
What makes you think you'd be playing around with pointers under the
hood?


If the function is outline, then the machine code will work with pointers to
access the memory.


It would likely access it indirectly, yes. But the compiler could
inline the function, and it may optimise away the use of any indirect
access. That was my point.
Please don't enter into a discussion which goes down the road of "A compiler
is free to implement features in whichever way it please, and doesn't have
to use pointers...".
I prefer "indirection", since the use of pointers implies that it will
actually add pointers to your source before compiling it.
So... my aim is to draw up some conventions for the use of A, B and C.

Firstly, when do I use method C?

1: When I want to alter the supplied variable.

But you don't, for a start it's const, and secondly you make a copy!


I was simply showing an alternative. I realise that I don't alter its value.


That did confuse me a little in combination with your functions above (I
didn't understand the use of const).
For built in types you are not going to modify do this:
T builtIn(T t) { return t; }

For non built in types do this:
T notBuiltin(const T& t) { return t; }

If you want to modify the parameter do this:

T& modify(T& t) { return t; }

Yes, but...

If we want to pass by value, thus not altering the variables value, we have
a choice of either:
(T is an intrinisc type:)

T SubtractSeven(T t) { return t -= 7; }


The function body looks weird (to me).
T SubtractSeven(T t) { return t - 7; }
All looks normal (to me).
Abiding by my "put const wherever I can rule", then the latter would be:

T SubtractSeven(T const t) { return t - 7; }
The function prototype looks weird (to me).
So when we're dealing with intrinsic types, do we go with:

(A) T SubtractSeven(T const t) { return t - 7; }
-or-
(B) T SubtractSeven(T t) { return t -= 7; }


You know I'm going to suggest a C!

Have fun :)

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 20 '06 #6
LuB

LuB wrote:
A: int SubtractSeven( int const x )
B: int SubtractSeven( int x )
C: int SubtractSeven( int const& x )

Keep in mind that 'x' here is passed by value in A and B. Therefore,
they are semantically the same functions. It is impossible for A or B
to alter the original x parameter. The 'const' notation becomes
irrelevant. I'd actually consider it 'confusing' since it is well known
that x is passed by value. The next person to look at this code might
wonder what you were trying to accomplish ... maybe you left off '&' or
something ...

In addition, unless you are using an environment where sizeof(&int) !=
sizeof(int) .. I don't think you gain a performance edge by using C
since, passing and int by value or reference moves the same number of
bits ...

Hth,

-LutherB


Oops. My apologies for the previous top post.

Feb 20 '06 #7
LuB wrote:

In addition, unless you are using an environment where sizeof(&int) !=
sizeof(int) .. I don't think you gain a performance edge by using C
since, passing and int by value or reference moves the same number of
bits ...


....followed by zero, one or more indirections, iff the "pointer" is not
optimised away.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 20 '06 #8
Ben Pope wrote:
Tomás wrote:
int SubtractSeven( int const x )
Not to the generated code, but readability may affected (one way or
another). Personally I would start to wonder why you had made it const
when it couldn't possibly be modified since it's passed by value. Then
I would wonder if you had intended it to be passed by reference.


How about it we want it so that x is const within SubtractSeven. Yes,
externally, they have the same effect, but it provides additional safety
inside of SubtractSeven.
Feb 20 '06 #9
In message <11**********************@o13g2000cwo.googlegroups .com>,
Dervish <DA*******@yandex.ru> writes
A: int SubtractSeven( int const x )
B: int SubtractSeven( int x )
C: int SubtractSeven( int const& x )

Problem with A is, that A & B has exactly the same signature from
compiler point of view. If two things are the same usually it is better
to use only one. And usually B is used. A is a little bit too puristic.

Speaking about C, I think it should be total taboo even mention about
possibility to pass built in types by const reference or pointer to
const.


Why? That would mean you have to make special cases for template code
which could otherwise be written identically for all argument types.

--
Richard Herring
Feb 20 '06 #10

red floyd wrote:
Ben Pope wrote:
Tomás wrote:
> int SubtractSeven( int const x )

Not to the generated code, but readability may affected (one way or
another). Personally I would start to wonder why you had made it const
when it couldn't possibly be modified since it's passed by value. Then
I would wonder if you had intended it to be passed by reference.


How about it we want it so that x is const within SubtractSeven. Yes,
externally, they have the same effect, but it provides additional safety
inside of SubtractSeven.


A couple of Herb Sutter's GOTW articles suggests that this isn't
helpful, although one is fairly thin on rationale.

http://www.gotw.ca/gotw/006.htm
http://www.gotw.ca/gotw/081.htm

I don't use const in this way - not so much because I have found it
detrimental, but really because I have not felt worse off for its
absence, and nobody else does it like that. Perhaps there's a certain
amount of exposing an implementation detail - this function does not
change it's copy of the parameter value - which is of no consequence to
the caller, which grates slightly with me. But the main reason I don't
do it is the reason for several of my C++ style choices: it's not the
commonly recognised idiom. And going against the principle of least
surprise for no real benefit is something I certainly want to avoid.

Gavin Denae

Feb 20 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Simon Harvey | last post by:
Whato chaps, I work (or am hoping to work! :) for a company that specialises in the following: - Localisation of media - including software, manuals, literature and training material. -...
19
by: John Salerno | last post by:
I just realized that the C# convention for uses braces is to put the opening brace immediately after the first line that defines the block (except for class declarations) like this: if...
0
by: Carl Colijn | last post by:
Hi all, Disclaimer: before I might trigger your "let's start a holy war!" button, I'd like to say I'm not intended to; I just post this message to get some input and not to promote "Yet Another...
17
by: Student | last post by:
Hi All, I have an assignment for my Programming language project to create a compiler that takes a C++ file as input and translate it into the C file. Here I have to take care of inheritance and...
3
by: Damian | last post by:
Has anyone on the team responsible for the smallbusiness starter kit every ran this thing on anything other than the Visual Studio Development Server. After spending time getting used to this kit...
16
by: Bruce W. Darby | last post by:
I've almost completed my little application for work. This weekend I've been working on Streams so I can write a logfile showing the work that was accomplished. Wanting to make each logfile...
2
by: Bharath | last post by:
Hi All, I am a newbie to C++ and I'm trying to figure this out. Can you please help? We have 3rd party library that's written in c++. We don't have the source for it. ldd on that shared...
169
by: JohnQ | last post by:
(The "C++ Grammer" thread in comp.lang.c++.moderated prompted this post). It would be more than a little bit nice if C++ was much "cleaner" (less complex) so that it wasn't a major world wide...
10
by: moondaddy | last post by:
Hi, I have 3 tiny content controls and each has a Path in it to draw some lines. These need to be very small and I'm having trouble making the lines clear. the lines have a stroke thickness of "1",...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.