0

I was reading this. That question contains following program.

#include <iostream>
#include <cstdio>
#include <string>
int main()
{
    using namespace std;
    string myString = "Press ENTER to quit program!";
    cout << "Come up and C++ me some time." << endl;
    printf("Follow this command: %s", myString);
    cin.get();
    return 0;
}

I tried it on g++ 4.8.1 & it fails in compilation. g++ 4.8.1 gives following diagnosis.

9 47 [Error] cannot pass objects of non-trivially-copyable type 'std::string {aka class std::basic_string<char>}' through '...' 
9 47 [Warning] format '%s' expects argument of type 'char*', but argument 2 has type 'std::string {aka std::basic_string<char>}' [-Wformat=]

What does this error mean? Should this program compile successfully or not? Which compiler is correct (g++ or MSVS 2010) ? Why MSVS 2010 accepts this code? Is the code invokes undefined behavior when compiled on MSVS 2010?

Surprising: I tried it on ideone which uses g++ 5.0 & surprisingly it compiles & runs fine. (See live demo here.). g++ 5.2.0 gives warning when I compile this code. (See live demo here). Why it compiles fine on ideone but fails on g++ 4.8.1? g++ 4.8.2(gives same diagnosis as g++ 4.8.1, 4.9.0,4.9.1,4.9.2 (gives error not warning). g++ 5.1.0 gives warning but program still compiles & runs fine.

Why different versions of g++ behave differently when compiling above program? Is this bug in g++ ? Clang also rejects this code to compile in response to answer given by @TemplateRex

8
  • Does it really run fine? None of the two live demo seems showing the content of myString correctly. Commented Sep 17, 2015 at 7:05
  • It gives errors because you are doing something that's not allowed, namely use C++ object with an old C function, which is simply not possible. Commented Sep 17, 2015 at 7:06
  • @JoachimPileborg: then why it compiles successfully without any errors on g++ 5.1.0, 5.2.0? Commented Sep 17, 2015 at 7:07
  • @StillLearning: This is not duplicate. If it is duplicate then I wouldn't link that question when posting this question. Commented Sep 17, 2015 at 7:07
  • 1
    See also stackoverflow.com/questions/10083844/… which specifically addresses why different versions may behave differently. Commented Sep 17, 2015 at 7:14

1 Answer 1

1

Clang errors out with "error: cannot pass non-trivial object of type 'string' (aka 'basic_string') to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs]" and suggests the fix "note: did you mean to call the c_str() method?"

#include <iostream>
#include <cstdio>
#include <string>
int main()
{
    using namespace std;
    string myString = "Press ENTER to quit program!";
    cout << "Come up and C++ me some time." << endl;
    printf("Follow this command: %s", myString.c_str());
    cin.get();
}

and it seems to work.

Sign up to request clarification or add additional context in comments.

5 Comments

If you remove call to c_str() function then it will fail in compilation & gives exactly same errors given by g++ 4.8.1, 4.8.2 , 4.9.0, 4.9.1 & 4.9.2
@PravasiMeet printf is not suited for std::string, just paste the c_str() to it and you're in business
Yes right. but question is why different compilers react differently when compiling this program?
@PravasiMeet in the Q&A given in the comments to your OP, it is pointed out that passing std::string to printf is undefined behavior. Anything can happend in that case, including successfull compilation and output. But you shouldn't rely on that.
@PravasiMeet - It is your responsibilty to match up the format string with the parameters. Some compilers might be nice and tell you when you fail that, but they don't have to. With some calling conventions, and on implementations where std::string happens to have a pointer as its first member, printf might believe it gets a C style string and display it correctly by accident.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.