Why this C++ program behave differently on different compilers? [duplicate] - c++

This question already has answers here:
printf with std::string?
(9 answers)
Closed 7 years ago.
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

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.

Related

Stoi was not declared in scope - Code::blocks

Edit: I'm trying to tell it to work with C++11 by clicking "Have g++ follow the C++11 ISO C++ language standard" in the compiler flags.
I'm getting stoi was not declared in scope, and I've added c++11 to Code::Blocks; I've added compatibility in Settings -> Compilers -> Compiler flags, but it still keeps giving me that error.
And when I try to do atoi or strtol I get the following error:
C:\Users\user\Desktop\Programming\NewProject\main.cpp|19|error: cannot
convert 'std::string {aka std::basic_string}' to 'const char*'
for argument '1' to 'long int strtol(const char*, char**, int)'|
My code:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
string numberGuessed;
int numberGuessedint = 0;
do {
cout << "Guess a number between 1 and 10: ";
getline(cin, numberGuessed);
numberGuessedint = stoi(numberGuessed);
cout << numberGuessedint << endl;
} while(numberGuessedint != 4);
cout << "You win!" << endl;
return 0;
}
It is a known bug in MinGW bundled with Code::Blocks.
You can apply a patch: http://tehsausage.com/mingw-to-string
Or download fresh version of MinGW (preferable with threading support, as you lack it too) and replace one you have right now.
To use atoi you need:
numberGuessedint = atoi(numberGuessed.c_str());
I am writing a solution which worked for me. As I found in most of the solutions posted on stack overflow, code blocks earlier versions contain a bug. So I deleted my older code blocks version and installed a new version 17.12 from code blocks website.
Then I just clicked on "Have g++ follow the C++11 ISO C++ language standard" in the compiler flags.
Settings -> Compilers -> Compiler flags.
It works for me(I am using windows 7).

libstdc++ doesn't recognise standard library literals

I'm trying to compile a simple program utilizing literals from the std::literals namespace, but Clang is generating errors when I try to compile it.
The code I'm trying to compile:
#include <string>
#include <iostream>
using namespace std::literals;
int main()
{
std::cout << "Hello World!"s << std::endl;
return 0;
}
and the compilation command:
clang++ -stdlib=libstdc++ -std=c++1y a.cpp
which leads to this output:
a.cpp:4:22: error: expected namespace name
using namespace std::literals;
~~~~~^
a.cpp:8:29: error: no matching literal operator for call to 'operator "" s' with arguments of
types 'const char *' and 'unsigned long', and no matching literal operator template
std::cout << "Hello World!"s << std::endl;
^
2 errors generated.
Using g++ or libc++ are out of the question for various reasons, and I've confirmed that other C++14 features (ie. return type deduction and binary literals) work, so it's not an issue with the compiler, making me believe it involves libstdc++.
What can I do to fix this? I'm on Linux Mint 17.1 if it makes any difference.
Remember to ensure that you're compiling the source according to C++14 (the chrono literals are not provided in C++11).
clang++ -stdlib=libstdc++ -std=c++14 a.cpp

Can't run to_string() function on Linux

I've got some code that I'm running on Mac OS X that can't be compiled on the Virtual Machine running Linux Mint. This is a simple example. When I run it in Mac, all is fine, but I'm getting issues when I run the same code on Linux, so I'm assuming the library I'm including is not there, but should I be getting an include error then?
Here's the example code that runs on Mac.
#include <iostream>
#include <stdlib.h>
#include <string>
#include <cstdlib>
using namespace std;
int main(){
for (int i = 0; i < 10; i++){
string test = to_string(i);
cout << test << endl;
}
cout << "done" << endl;
return 0;
}
I get no issues here but running on Linux Mint, I get this when I try to compile:
for.cpp: In function 'int main()':
for.cpp:7:28 error: 'to_string' was not declared in this scope
string test = to_string(i);
^
make: *** [for] Error 1
Am I missing something? Any help would be much appreciated!
edit
I realize I forgot to include <string> on here and I fixed it, but what I changed (<string> included) still doesn't compile on Linux. I've used to_string before. I know that much in C++. I also tried adding <cstdlib>. Once again, this DOES compile on Mac and DOES NOT compile on Linux.
Here is my OSX output:
0
1
2
3
4
5
6
7
8
9
done
Here is my output on Linux Mint (Once again, Virtual Box, g++ make):
test.cpp: In function ‘int main()’:
test.cpp:9:28: error: ‘to_string’ was not declared in this scope
string test = to_string(i);
^
make: *** [test] Error 1
You could reproduce the problem yourself if you don't believe me. It's the same code, you can see for yourself if you want.
Compile your for.cpp file like this:
g++ -std=c++11 for.cpp
and run it with:
./a.out
The support for the to_string function in the <string> header was added in the C++11 version of the language, so you need to tell GCC to use that version. You can use the c++0x flag too, for example:
g++ -std=c++0x for.cpp
And you don't have to worry about <cstdlib>, that has nothing to do with it...
to_string() is defined in <string> if you are compiling with C++11 (but is not defined, or unreliably defined as an extension feature, if you are compiling with an earlier version of C++).
Reference: http://en.cppreference.com/w/cpp/string/basic_string/to_string
SOLUTION:
I found a better solution. For some reason, I've read stdlib.h will not work on some linux systems. I used a different function to convert int to string.
on linux:
#include <stdio.h>
and then
for (int i = 0; i < 10; i++){
char buffer[10];
sprintf(buffer,"%d",i);
string stringInt = buffer;
cout << stringInt << endl;
// do whatever you want with the string
}
edit
To the person that down voted my solution to this, here's a post from six years ago basically saying the same thing.

<thread>: no match for operator <

I am trying to implement mutlithreading in a C++11 program.
I separated the threading from my main program and tried to get the most basic example working:
#include <iostream>
#include <thread>
void first_procedure() {
std::cout << "First procedure output." << std::endl;
}
void second_procedure() {
std::cout << "Second procedure output." << std::endl;
}
int main() {
std::thread first_thread(first_procedure);
std::thread second_thread(second_procedure);
first_thread.join();
second_thread.join();
return 0;
}
However, even with this example, I get the following error:
c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread In function 'bool std::operator<(std::thread::id, std::thread::id)':
88 30 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\thread [Error] no match for 'operator<' (operand types are 'std::thread::native_handle_type {aka ptw32_handle_t}' and 'std::thread::native_handle_type {aka ptw32_handle_t}')
I am using the Orwell Dev-C++ 5.7.1 with TDM-GCC 4.7.1 64-bit on Windows 8. When calling the linker, I add -static-libgcc -std=c++11.
Edit 1: I joined the threads and get the same error message.
This was noticed in the comments first:
From your error messages and supplementary details:
compiler: TDM-GCC 4.7.1
includes: gcc\x86_64-w64-mingw32\4.8.1\include
Your compiler is attempting to use libraries that are for a different compiler.
Either use 4.7.1 or 4.8.1, not a mix of the two.
The good news is that your code looks fine. Sort out the toolchain and it should compile without issue.

Why are std::stoi and std::array not compiling with g++ c++11?

I've been learning C++ and using the Terminal for the last couple of months. My code was compiling and running fine using g++ and C++11, but in the last couple of days it started giving errors and I have had problems compiling since. The only programs I can compile and run depend on older C++ standards.
The errors I first got related to #include < array > in the header file. Not sure why this happened, but I got around it by using boost/array instead. Another error I can't solve is with std::stoi. Both array and stoi should be in the C++11 standard library. I made the following simple code to demonstrate what's going on:
//
// stoi_test.cpp
//
// Created by ecg
//
#include <iostream>
#include <string> // stoi should be in here
int main() {
std::string test = "12345";
int myint = std::stoi(test); // using stoi, specifying in standard library
std::cout << myint << '\n'; // printing the integer
return(0);
}
Try to compile using ecg$ g++ -o stoi_trial stoi_trial.cpp -std=c++11
array.cpp:13:22: error: no member named 'stoi' in namespace 'std'; did you mean
'atoi'?
int myint = std::stoi(test);
~~~~~^~~~
atoi
/usr/include/stdlib.h:149:6: note: 'atoi' declared here
int atoi(const char *);
^
array.cpp:13:27: error: no viable conversion from 'std::string' (aka
'basic_string') to 'const char *'
int myint = std::stoi(test);
^~~~
/usr/include/stdlib.h:149:23: note: passing argument to parameter here
int atoi(const char *);
^
2 errors generated.
I also get these errors at compilation when using gcc or clang++ and with -std=gnu++11 (I guess they all depend on the same file structure). I also get the same error whether I specify std:: in the code, or if I specify using namespace std;
I worry that these issues arose because of the September Command Line Tools update via Xcode or because I installed boost and this somehow messed up my C++11 libraries. Hopefully there is a simple solution.
My system:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-> dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
Thanks for any insight you can offer.
clang has a weird stdlib, you need to add the following flag when you compile
-stdlib=libc++
your snippet works on my mac with
g++ -std=gnu++11 -stdlib=libc++ test.cpp -o test
This answer describes the problem