473,508 Members | 2,373 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

initialization problem

Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}

This code is the consequence of lazy Search/Replace (s/msg0/msg/g -
initially the function parameter and the first variable after the _=_
was msg0).
But shouldn't the compiler complain about the initialization of an
object use the same object? What am I missing?

TIA,

Marcelo Pinto

Dec 20 '05 #1
15 2013

Marcelo Pinto wrote:
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}
But shouldn't the compiler complain about the initialization of an

object use the same object? What am I missing?


Which compiler? The above code (after removing all extra portion) gives
redeclaration error with Comeau online (msg has already been declared
in the current scope)

Dec 20 '05 #2
Marcelo Pinto wrote:
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}

This code is the consequence of lazy Search/Replace (s/msg0/msg/g -
initially the function parameter and the first variable after the _=_
was msg0).
But shouldn't the compiler complain about the initialization of an
object use the same object? What am I missing?


you are allowed to redeclare already visible identifiers in different
scopes. only redefining an identifier that has already been defined in
the same scope is illegal and yields a compiler error.

your for() loop body is a new scope, thus the identifier msg can be
defined again. you have to be aware though that you are effectively
hiding the already visible identifier, which is probably not what you
intended to do.

-- peter

Dec 20 '05 #3
Neelesh Bodas wrote:
Marcelo Pinto wrote:
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}

But shouldn't the compiler complain about the initialization of an


object use the same object? What am I missing?

Which compiler? The above code (after removing all extra portion) gives
redeclaration error with Comeau online (msg has already been declared
in the current scope)


Really? Did you remove the 'for' as well? It's introduces the proper
scope limitation for the "inner" msg...

V
Dec 20 '05 #4
Neelesh Bodas wrote:
Marcelo Pinto wrote:
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}
But shouldn't the compiler complain about the initialization of an

object use the same object? What am I missing?


Which compiler? The above code (after removing all extra portion) gives
redeclaration error with Comeau online (msg has already been declared
in the current scope)


you probably removed a little bit too much of the given example... ;-)

-- peter

Dec 20 '05 #5
Marcelo Pinto wrote:
void f(const std::string & msg)
{ { std::string msg = msg + " " + another_string; //1 } }
.... But shouldn't the compiler complain about the initialization of an
object use the same object? What am I missing?


The Standard clearly states, that in

int x = 12;
{ int x = x; }

the second _x_ is initialized with its own (indeterminate) value.

But in this particular case I wonder what will happen, since _msg_
should probably be constructed before it is used. My belief is that
_msg_ will be constructed with the default constructor, then the
expression will be evaluated and then the assignment operator will be
called.

Martin.
Dec 20 '05 #6

"Marcelo Pinto" <mp******@gmail.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
This is legal. This msg local to the for loop hides the msg parameter. So
it basically becomes:
std::string msg = "" + " " + another_string;

which is probably why you're asking.

No, there are generally no compiler warnings for hiding variables. Although
there generally are for hiding methods in classes.
//...
}
//...
}

This code is the consequence of lazy Search/Replace (s/msg0/msg/g -
initially the function parameter and the first variable after the _=_
was msg0).
But shouldn't the compiler complain about the initialization of an
object use the same object? What am I missing?

TIA,

Marcelo Pinto

Dec 20 '05 #7

Neelesh Bodas escreveu:
Which compiler? The above code (after removing all extra portion) gives
redeclaration error with Comeau online (msg has already been declared
in the current scope)


aCC: HP ANSI C++ B3910B A.03.37

Dec 20 '05 #8
Neelesh Bodas wrote:
Marcelo Pinto wrote:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1
//...
}
//...
}

Which compiler? The above code (after removing all extra portion) gives
redeclaration error with Comeau online (msg has already been declared
in the current scope)


It can hardly be redeclared as long as it is in the inner scope. You
probably removed the "extra" for loop. Don't do that or at least remove
only `for (...)` line.

Martin.
Dec 20 '05 #9
Jim Langston wrote:
"Marcelo Pinto" <mp******@gmail.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
Hi,

Consider the following code snipet:
void f(const std::string & msg)
{
//...
for (...)
{
//...
std::string msg = msg + " " + another_string; //1


This is legal. This msg local to the for loop hides the msg parameter. So
it basically becomes:
std::string msg = "" + " " + another_string;

which is probably why you're asking.

No, there are generally no compiler warnings for hiding variables. Although
there generally are for hiding methods in classes.


The local "msg" variable is accessed before it has been initialized
(because it is used in its own initializer.) Since the value of the msg
variable is indeterminate before its initialization, the outome of this
expression, though legal, is undefined.

Greg

Dec 20 '05 #10

Victor Bazarov wrote:
Really? Did you remove the 'for' as well? It's introduces the proper
scope limitation for the "inner" msg...


Yeah ;-) I removed everything which caused trouble for compilation :-)

-N

Dec 21 '05 #11

"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Jim Langston wrote:
"Marcelo Pinto" <mp******@gmail.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
> Hi,
>
> Consider the following code snipet:
>
>
> void f(const std::string & msg)
> {
> //...
> for (...)
> {
> //...
> std::string msg = msg + " " + another_string; //1


This is legal. This msg local to the for loop hides the msg parameter.
So
it basically becomes:
std::string msg = "" + " " + another_string;

which is probably why you're asking.

No, there are generally no compiler warnings for hiding variables.
Although
there generally are for hiding methods in classes.


The local "msg" variable is accessed before it has been initialized
(because it is used in its own initializer.) Since the value of the msg
variable is indeterminate before its initialization, the outome of this
expression, though legal, is undefined.

Greg


Actually, I was reading somewhere that
std::string msg("Hello");
is more effecient than
std::string msg = "Hello";

Because one uses the regular constructor, one uses the assignment
constructor.

If the assignment constructor is uses, isn't the default constructor called
first? Or am I mistaken on that?
Dec 21 '05 #12

Jim Langston wrote:
"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Jim Langston wrote:
"Marcelo Pinto" <mp******@gmail.com> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
> Hi,
>
> Consider the following code snipet:
>
>
> void f(const std::string & msg)
> {
> //...
> for (...)
> {
> //...
> std::string msg = msg + " " + another_string; //1

This is legal. This msg local to the for loop hides the msg parameter.
So
it basically becomes:
std::string msg = "" + " " + another_string;

which is probably why you're asking.

No, there are generally no compiler warnings for hiding variables.
Although
there generally are for hiding methods in classes.


The local "msg" variable is accessed before it has been initialized
(because it is used in its own initializer.) Since the value of the msg
variable is indeterminate before its initialization, the outome of this
expression, though legal, is undefined.

Greg


Actually, I was reading somewhere that
std::string msg("Hello");
is more effecient than
std::string msg = "Hello";

Because one uses the regular constructor, one uses the assignment
constructor.

If the assignment constructor is uses, isn't the default constructor called
first? Or am I mistaken on that?


No, an object's constructor is not called before an object is
initialized with itself. For example, compiling and running this
program:

#include <string>

int main()
{
std::string s = s + "hello";
}

terminates with a segmentation fault on my machine. It crashes because
the program is accessing s's storage as if it were a constructed
std::string. Although the Standard does not require that any warning be
issued, gcc does have a special switch, -Winit-self, to check for this
kind of mistake (though I can't imagine it is all that common). But it
is not entirely straightforward, since enabling the warning requires
that two other switches also be set.

Actually these declarations:

std::string msg("Hello");
std::string msg = "Hello";

are equivalent. Both call the same constructor. The use of the "=" in
one is confusing since it looks very much like last line in this
sequence:

std::string msg;

msg = "Hello";

In this case, there is a call to the std::string's assignment operator
because msg has already been constructed. In general, the rule-of-thumb
is to prefer construction over assignment (as in a loop for example)
since construction is usually more efficient. I'm not sure whether that
is the case with std::string, though I can't think of any reason why it
would not be.

Greg

Dec 21 '05 #13

Greg escreveu:
The local "msg" variable is accessed before it has been initialized
(because it is used in its own initializer.) Since the value of the msg
variable is indeterminate before its initialization, the outome of this
expression, though legal, is undefined.

Greg


That is precisely how I interpreted it. But in that case shouldn't the
compiler have warned? Is this valid C++ (acording to the Standard)? Is
it UB?

TIA,

Marcelo Pinto

Dec 21 '05 #14

Greg wrote:
Actually these declarations:

std::string msg("Hello");
std::string msg = "Hello";

are equivalent. Both call the same constructor. The use of the "=" in
one is confusing since it looks very much like last line in this
sequence:


in this case because the constructor of std::string from const char *
is implicit (and the general rule that does not allow 2 implicit
conversions does not apply converting char[6] to const char*).

But if a class were declared with an explicit constructor the second
version should fail to compile.

This however should also be equivalent:

std::string msg = std::string("Hello");

and will not call operator= nor invoke a copy-constructor even without
RVO.
(Try it on a class that has copy-construction and assignment disabled
and an explicit constructor).

Dec 21 '05 #15
"Jim Langston" <ta*******@rocketmail.com> writes:
Actually, I was reading somewhere that
std::string msg("Hello");
is more effecient than
std::string msg = "Hello";

Because one uses the regular constructor, one uses the assignment
constructor.
What is "the assignment constructor"?

Constructors are "special member functions" that construct objects.
A constructor that doesn't take any arguments is usually called
default constructor, and one that takes a reference to another
object of the same type is called copy constructor.

Assignment is usually spelled operator =, and is something else.
If the assignment constructor is uses, isn't the default constructor called
first? Or am I mistaken on that?


#include <string>

using std::string;

int main()
{
std::string msg1("Hello"); // 1
std::string msg2 = "Hello"; // 2
return 0;
}

In theory line 1 calls uses a constructor taking a char* argument,
and line 2 first constructs an anonymous temporary object using
the same constructor as line 1, and then uses the copy constructor
to create msg2. In practice the two lines are equivalent, since
the creation of the temporary is optimized away. (For classes
where the copy constructor is private or protected line 2 doesn't
compile though).

/Niklas Norrthon

Dec 21 '05 #16

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

Similar topics

2
4012
by: Vinay Aggarwal | last post by:
I have been thinking about the lazy initialization and double checked locking problem. This problem is explain in detail here http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html...
4
1877
by: Russell Silva | last post by:
I have a class A with a member variable type vector<foo> which is initialized upon construction (no standard () constructor): class A { protected: vector<foo> foo_vector; public: A(const...
3
3582
by: DanielBradley | last post by:
Hello all, I have recently been porting code from Linux to cygwin and came across a problem with static const class members (discussed below). I am seeking to determine whether I am programming...
10
4163
by: JKop | last post by:
What's the difference between them? Take the following: #include <iostream> struct Blah { int k;
4
2763
by: Brian Folke Seaberg | last post by:
I have been examining the documentation for a class library written in C++. It seems that most of the classes in that library use two stage initialization. Objects are not ready for use after...
4
2192
by: Anton Pervukhin | last post by:
Hi everybody! I have a small problem regarding the initialization of pointer to the file stream under some conditions. Imagine a class which has a pointer to output file stream and some...
49
2266
by: Luke Meyers | last post by:
Lately I find myself increasingly preferring the practice of going ever-so-slightly out of my way to avoid the use of the form of initialization which uses the '=' symbol, on the grounds that it...
5
6759
by: Jesper Schmidt | last post by:
When does CLR performs initialization of static variables in a class library? (1) when the class library is loaded (2) when a static variable is first referenced (3) when... It seems that...
3
5830
by: Steve Folly | last post by:
Hi, I had a problem in my code recently which turned out to be the 'the "static initialization order fiasco"' problem (<http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12>) The FAQ...
11
2390
by: subramanian100in | last post by:
Suppose we have a class named Test. Test obj; // assuming default ctor is available Test direct_init(obj); // direct initialization happens here Test copy_init = obj; // copy initialization...
0
7223
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
7115
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7321
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7377
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
5624
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,...
1
5047
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3191
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3179
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1547
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.