22

In one function of my code I found a bug. It was written std:string :

const std::string currentDateTime() {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    //strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
    strftime(buf, sizeof(buf), "%Y%m%d%X", &tstruct);

    std:string str = buf;

    str.erase(std::remove(str.begin(), str.end(), ':'), str.end());
    return str;
}

The code compiles without errors. Why does it compile? What does std:string mean then?

A. Jesse Jiryu Davis
  • 23,641
  • 4
  • 57
  • 70
vico
  • 17,051
  • 45
  • 159
  • 315
  • 9
    `std:` is a label, there must be a using in there someplace. – Shafik Yaghmour Oct 09 '15 at 12:14
  • 2
    This code only works if you are doing "using namespace std" which is IMO bad anyway. Otherwise this would have been caught as a compile error unless there is a type string somewhere defined. – Devolus Oct 09 '15 at 12:16
  • 2
    @Devolus You can also do using std::string, to get this same effect. – dascandy Oct 09 '15 at 12:19
  • 1
    Both clang and gcc provide an unused label warning for this. – Shafik Yaghmour Oct 09 '15 at 12:20
  • I recently found and fixed that same bug in some code coworkers wrote. Bug #1, there was a `using namespace std;` in an include file where it really really should not have been. Fix bug #1 and compiling failed on bug #2 `std:string` – JSF Oct 09 '15 at 12:39

3 Answers3

20

It is interpreted as a label that can be used with goto.

int main()
{
    //label to jump to:
    label_name:
    //some code
    <..>
    //some code
    goto label_name;//jump to the line with the lable
}

Obviously that was a typo. Your code compiled because using namespace std; or using std::string was used somewhere above. Otherwise you'd get a "string was not declared in this scope" error.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
6

I think it compiles because the infamous "using namespace std;" directive was used above in the file ( or worse, in another included file ).

So the compiler sees "std:" as a goto label, and uses (std::)string because "using namespace std" was used.

Normally on modern compiler you may have a warning, something like (in gcc):

  warning: label ‘std’ defined but not used
Nikko
  • 4,182
  • 1
  • 26
  • 44
  • 1
    There are a couple of issues with this answer, `using namespace std;` is not the only way for this to come up and although it is true gcc can warn for this the OP tagged the question Visual C++ and the warning are not automatic you need to turn them on. If they were automatic the OP would have discovered the problem and never have asked the question. So the root of the problem is not having warnings turned on. – Shafik Yaghmour Oct 09 '15 at 13:03
6

std: is being used as a label which can be used as the target of a goto. There must be a using directive someplace in your code either:

using std::string;

or:

using namespace std; 

Also see Why is “using namespace std;” considered bad practice?.

This demonstrates the importance of using warnings. I can get Visual Studio, gcc and clang to warn for this using the correct flags. For Visual Studio using /W3 gives the following warning (see it live):

warning C4102: 'std' : unreferenced label

For this code:

#include <string>

using std::string ;

int main()
{
    std:string s1 ;
}

For gcc and clang using -Wall was sufficient, for gcc I receive the following:

warning: label 'std' defined but not used [-Wunused-label]
 std:string s1 ;
 ^

and a similar warning from clang.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740