14

Say I have the below (very simple) code.

#include <iostream>
int main() {
    std::cout << std::stoi("12");
}

This compiles fine on both g++ and clang; however, it fails to compile on MSVC with the following error:

error C2039: 'stoi': is not a member of 'std'

error C3861: 'stoi': identifier not found

I know that std::stoi is part of the <string> header, which presumably the two former compilers include as part of <iostream> and the latter does not. According to the C++ standard [res.on.headers]

A C++ header may include other C++ headers.

Which, to me, basically says that all three compilers are correct.

This issue arose when one of my students submitted work, which the TA marked as not compiling; I of course went and fixed it. However, I would like to prevent future incidents like this. So, is there a way to determine which header files should be included, short of compiling on three different compilers to check every time?

The only way I can think of is to ensure that for every std function call, an appropriate include exists; but if you have existing code which is thousands of lines long, this may be tedious to search through. Is there an easier/better way to ensure cross-compiler compatibility?

Example with the three compilers: https://godbolt.org/z/kJhS6U

10
  • 6
    If you remember that std::stoi is for handling strings you could guess that <string> would be a good header to include. Or you could search for a good reference which will tell you. And I recommend that you always explicitly include the header files, so you don't have to rely on non-portable implementation specific behavior. Commented Nov 27, 2019 at 12:31
  • 3
    Best way is to go to cppreference before going to any other platform. They have pretty detailed stuff there. Commented Nov 27, 2019 at 12:33
  • 1
    Include the appropriate header the moment you write the code. Ie. the moment you write code that contains, std::stoi, you immediately make sure #include <string> is present as well. Commented Nov 27, 2019 at 12:33
  • 3
    In the general case this is a difficult problem. However, when we are talking about missing standard library includes, the normal way would indeed be to examine all function calls/types used. Commented Nov 27, 2019 at 12:33
  • 1
    @skratchi.at, students are told they can use whichever compiler they want, so long as their code is standard-conforming. After 4 years, this is the first time this has ever been an issue. Commented Nov 27, 2019 at 12:57

2 Answers 2

16

Is there an easier/better way to ensure cross-compiler compatibility?

This is always going to be a bit of a chore if you have a huge codebase and haven't been doing this so far, but once you've gone through fixing your includes, you can stick to a simple procedure:

When you write new code that uses a standard feature, like std::stoi, plug that name into Google, go to the cppreference.com article for it, then look at the top to see which header it's defined in.

Then include that, if it's not already included. Job done!

(You could use the standard for this, but that's not as accessible.)

Do not be tempted to sack it all off in favour of cheap, unportable hacks like <bits/stdc++.h>!


tl;dr: documentation

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

10 Comments

To be fair, once you've effectively memorised them all and don't need to look it up any more, that feels pretty slick
@JosephWood: If you don't know which header a given function is by rote, chances are you should look the function up to double-check your assumptions on it anyway, so finding out which header it belongs to doesn't even take extra time.
Like @JosephWood, I was also hoping those with more experience had a better way. I know which headers to include for most STL functions, but was hoping there's an easier way to teach students than to look up every function :P
@ChrisMM there are tools like include-what-you-use. Their correctness cannot be guaranteed (and indeed sometimes manual work is necessary) but it's not bad at all.
@ChrisMM Teaching your students to refer to the documentation is incredibly, incredibly important. Thousands stream onto this site every day with no earthly idea that they should do it. Using the documentation is the easier/better way.
|
-1

Besides reviewing documentation and doing that manually (painful and time consuming) you can use some tools which can do that for you.

You can use ReSharper in Visual Studio which is capable to organize imports (in fact VS without ReSharper is not very usable). If include is missing it recommends to add it and if it is obsolete line with include is shown in more pale colors.

Or you can use CLion (available for all platforms) which also has this capability (in fact this is the same manufacture JetBrains).

There is also tool called include what you used, but its aim is take advantages of forward declaration, I never used that (personally - my team mate did that for our project).

1 Comment

clion doesn't autoinclude of correct header when other header is already included if works(ie. will not suggest string here if iostream is already included) IIRC

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.