Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Putting two colons before std -- is it ever needed?

50 views
Skip to first unread message

Frederick Gotham

unread,
Sep 25, 2019, 4:02:13 AM9/25/19
to

Occasionally I see people write code like this:

#include <string>

int main()
{
::std::string str;
}

I think you would only ever need to put those two colons before 'std' if you created a class or a namespace called 'std', and of course if you did, then it would have to be inside another namespace (because otherwise you'd have a name clash).

I tried compiling the following code, and each time it created a 'string' from the C++ standard library.

So the question I ask is if there is **ever** any situation when it's necessary to put two colons before 'std'?

#include <string>
#include <iostream>

namespace Monkey {

class nonstd {
int i;
};

class mutant : public nonstd {
int j;
};

class mongrel : public nonstd {
int k;
};

class std {
public:
typedef char *string;
};
}

int SomeFunc()
{
using namespace Monkey;

std::string a;

::std::string b;

::std::cout << sizeof(a) << " " << sizeof(b) << ::std::endl;
}

int main()
{
std::string a;

::std::string b;

::std::cout << sizeof(a) << " " << sizeof(b) << ::std::endl;

SomeFunc();
}




Ian Collins

unread,
Sep 25, 2019, 4:15:47 AM9/25/19
to
On 25/09/2019 20:02, Frederick Gotham wrote:
>
> Occasionally I see people write code like this:
>
> #include <string>
>
> int main()
> {
> ::std::string str;
> }
>
> I think you would only ever need to put those two colons before 'std' if you created a class or a namespace called 'std', and of course if you did, then it would have to be inside another namespace (because otherwise you'd have a name clash).
>
> I tried compiling the following code, and each time it created a 'string' from the C++ standard library.
>
> So the question I ask is if there is **ever** any situation when it's necessary to put two colons before 'std'?

In theory, maybe. In practice, no never.

--
Ian

David Brown

unread,
Sep 25, 2019, 6:22:16 AM9/25/19
to
On 25/09/2019 10:02, Frederick Gotham wrote:
>
> Occasionally I see people write code like this:
>
> #include <string>
>
> int main()
> {
> ::std::string str;
> }
>
> I think you would only ever need to put those two colons before 'std' if you created a class or a namespace called 'std', and of course if you did, then it would have to be inside another namespace (because otherwise you'd have a name clash).
>
> I tried compiling the following code, and each time it created a 'string' from the C++ standard library.
>
> So the question I ask is if there is **ever** any situation when it's necessary to put two colons before 'std'?
>

I believe it is possible to cause conflicts with "std" that could be
avoided by using "::std". But it would have to be malicious and
carefully crafted, or totally inept and highly unlucky. Since there are
few programmers in either category, and if you have either type in your
team then you have far bigger problems than can be solved with "::std",
it is basically a non-issue.

Some people in this group use it, but IMHO it is more about making the
code /look/ like it is super-robust, than actually being good practice.
The drop in readability is not justified by the miniscule improvement
in robustness or portability.


Frederick Gotham

unread,
Sep 25, 2019, 6:48:46 AM9/25/19
to
On Wednesday, September 25, 2019 at 11:22:16 AM UTC+1, David Brown wrote:
>
> I believe it is possible to cause conflicts with "std" that could be
> avoided by using "::std". But it would have to be malicious and
> carefully crafted, or totally inept and highly unlucky. Since there are
> few programmers in either category, and if you have either type in your
> team then you have far bigger problems than can be solved with "::std",
> it is basically a non-issue.

There are some groups of skilled people, that if you pick a person at random, you're very likely to get a bad one.

I've always thought that computer programmers were such a group of people. What I meant to say is: There are of course some very competent computer programmers, and even some expert ones, but if you pick one at random, you'll probably get a bad one.

It is my personal opinion that this holds true for some professions... I'd name a few but I don't want to get the ball rolling on that one. . .

Bo Persson

unread,
Sep 25, 2019, 9:48:49 AM9/25/19
to
It would be a problem if SomeFunc() were also a member of the Monkey
namespace, and one of your coworkers added his own std::string to it.

It that case it is probably time better spent to have a serious talk
with your collegue, rather than to fill up the code base with millions
of :: during the next decades.


Bo Persson



James Kuyper

unread,
Sep 25, 2019, 10:03:00 AM9/25/19
to
#include <iostream>
#include <cstdio>
namespace kuyper {
namespace std {
void printf(const char *txt) {
::std::cout << "Kuyper::std::" << txt;
}

void func(void)
{
std::printf("printf\n");
::std::printf("::std::printf\n");
}
}
}

int main(void)
{
kuyper::std::func();
return 0;
}

Compiled using g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
with the following command line:
g++ -std=c++1y -pedantic -Wall -Wpointer-arith -Wcast-align
-fno-enforce-eh-specs -ffor-scope -fno-gnu-keywords
-fno-nonansi-builtins -Wctor-dtor-privacy -Wnon-virtual-dtor
-Wold-style-cast -Woverloaded-virtual -Wsign-promo std.cpp -o std

Execution produces the following results:
Kuyper::std::printf
::std::printf

Code where std: is simply ambiguous, and must therefore be replaced by
::std if that's what you want to use is slightly simpler to create, but
is ill-formed. You need well-formed code like that above to make an
alternative namespace std be a preferred match to an unqualified std::.

James Kuyper

unread,
Sep 25, 2019, 10:11:32 AM9/25/19
to
On 9/25/19 10:02 AM, James Kuyper wrote:
...
> #include <iostream>
> #include <cstdio>
> namespace kuyper {
> namespace std {
> void printf(const char *txt) {
> ::std::cout << "Kuyper::std::" << txt;
> }
>
> void func(void)
> {
> std::printf("printf\n");
> ::std::printf("::std::printf\n");
> }
> }
> }
>
> int main(void)
> {
> kuyper::std::func();
> return 0;
> }

I made a mistake while creating that code, and after correcting that
mistake I forgot that it invalidated some of my earlier test results.
func() doesn't need to be defined inside ::kuyper::std; it's sufficient
if it's declared inside ::kuyper.

Frederick Gotham

unread,
Sep 25, 2019, 10:17:49 AM9/25/19
to
On Wednesday, September 25, 2019 at 3:03:00 PM UTC+1, James Kuyper wrote:

> #include <iostream>
> #include <cstdio>
> namespace kuyper {
> namespace std {
> void printf(const char *txt) {
> ::std::cout << "Kuyper::std::" << txt;
> }
>
> void func(void)
> {
> std::printf("printf\n");
> ::std::printf("::std::printf\n");
> }
> }
> }
>
> int main(void)
> {
> kuyper::std::func();
> return 0;
> }



It just occurred to me that it might make sense to deliberately leave out the two colons before 'std' so that you can at a later date pull off a little hack like this.

Stuart Redmann

unread,
Sep 25, 2019, 1:51:11 PM9/25/19
to
The majority of the readers of this group consider the additional :: as
unnecessary noise since every coding guideline should forbid to define your
own namespace std (inside one of your own namespaces; adding stuff to the
global namespace std is AFAIK forbidden by the standard).

However, a nested namespace std could be the result of auto-generated code,
for example from some ORM framework. In that case I'd assume that the
auto-generated code always uses fully qualified identifiers if there could
be the slightest chance of clashes. For example, if there is a persistence
module "std" containing an entity called "sin", it could clash with
::std::sin. So if the auto-generated code needed to call ::std::sin, it
should do so by using a full qualification.

Hand-written code should never need the additional qualification.

Regards,
Stuart

James Kuyper

unread,
Sep 25, 2019, 3:38:09 PM9/25/19
to
On 9/25/19 1:51 PM, Stuart Redmann wrote:
...
> ... adding stuff to the
> global namespace std is AFAIK forbidden by the standard).

The relevant rule is a little more complicated than a simple prohibition:

"The behavior of a C ++ program is undefined if it adds declarations or
definitions to namespace std or to a namespace within namespace std
unless otherwise specified. A program may add a template specialization
for any standard library template to namespace std only if the
declaration depends on a user-defined type and the specialization meets
the standard library requirements for the original template and is not
explicitly prohibited." (20.5.4.2.1p1).

Frederick Gotham

unread,
Sep 26, 2019, 3:01:39 AM9/26/19
to
On Wednesday, September 25, 2019 at 6:51:11 PM UTC+1, Stuart Redmann wrote:

> The majority of the readers of this group consider the additional :: as
> unnecessary noise since every coding guideline should forbid to define your
> own namespace std (inside one of your own namespaces; adding stuff to the
> global namespace std is AFAIK forbidden by the standard).
>
> However, a nested namespace std could be the result of auto-generated code,
> for example from some ORM framework. In that case I'd assume that the
> auto-generated code always uses fully qualified identifiers if there could
> be the slightest chance of clashes. For example, if there is a persistence
> module "std" containing an entity called "sin", it could clash with
> ::std::sin. So if the auto-generated code needed to call ::std::sin, it
> should do so by using a full qualification.
>
> Hand-written code should never need the additional qualification.


Shouldn't the auto-generated code just simply use prefixes/suffixes to avoid this, e.g. "_autogen__std" instead of "std"?

Vir Campestris

unread,
Sep 26, 2019, 4:52:13 PM9/26/19
to
On 25/09/2019 14:48, Bo Persson wrote:
>
> It would be a problem if SomeFunc() were also a member of the Monkey
> namespace, and one of your coworkers added his own std::string to it.
>
> It that case it is probably time better spent to have a serious talk
> with your collegue, rather than to fill up the code base with millions
> of :: during the next decades.

Well put.

There's an explicit prohibition of calling anything std in our coding
standards.

Andy

woodb...@gmail.com

unread,
Sep 27, 2019, 11:51:11 AM9/27/19
to
It's an easy step to take to improve the safety of your code.
In this 29 line program:
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/genz.cc

there's one ::std.

In this 228 line program:
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/cmwA.cc

there are 10 uses of ::std. If I remember right Gabriel Dos Reis
is also a proponent. Maybe Howard Hinnant also. It's kind of
like "east const".



Brian
Ebenezer Enterprises "We few, we happy few. We band of brothers."
St. Crispin's Day

http://webEbenezer.net

Scott Lurndal

unread,
Sep 27, 2019, 12:25:46 PM9/27/19
to
woodb...@gmail.com writes:
>On Wednesday, September 25, 2019 at 3:02:13 AM UTC-5, Frederick Gotham wrote:

>> So the question I ask is if there is **ever** any situation when it's necessary to put two colons before 'std'?
>>

>
>It's an easy step to take to improve the safety of your code.

It has absolutely nothing to do with code safety.

>In this 29 line program:

Snip blatent product placement. You haven't justified your statement about
code safety.

woodb...@gmail.com

unread,
Sep 27, 2019, 2:40:49 PM9/27/19
to
On Friday, September 27, 2019 at 11:25:46 AM UTC-5, Scott Lurndal wrote:
> woodb...@gmail.com writes:
> >On Wednesday, September 25, 2019 at 3:02:13 AM UTC-5, Frederick Gotham wrote:
>
> >> So the question I ask is if there is **ever** any situation when it's necessary to put two colons before 'std'?
> >>
>
> >
> >It's an easy step to take to improve the safety of your code.
>
> It has absolutely nothing to do with code safety.
>
> >In this 29 line program:
>
> Snip blatent product placement.

I think of it as a service not a product.
Products in my experience aren't free.


Brian

Scott Lurndal

unread,
Sep 27, 2019, 4:19:56 PM9/27/19
to
Neither are useful services.
0 new messages