eric
eric

Reputation: 8019

How to determine which include header file a function comes from?

When learning new functions, I like to include the full name when calling them (e.g., std::cin instead of cin). Is there a similar way to include the header that the function came from? E.g., is there a way to specify the sort function is from the <algorithm> header, and not the <iomanip> header, or whatever?

For instance, it would be cool if I could call sort using something like std::algorithm::sort instead of std::sort. There are so many headers built in to the standard library that just using std::* is not actually that informative, and tells me very little specifically about where * is coming from.

Obviously as I get better with C++ this might not be necessary, but my goal is to learn which functions go with which headers to better learn the standard library.

If there is no such way to specify the function, is there a function I can use to determine which header supplied the function?

Ultimately I think it will be good coding practice to list the functions you will be using that are associated with each header:

#include <iostream>  //std::cout, std::cin

That way people can figure out what comes from where! Why is this not done more, given c++ community's admirable obsession with clarity about names?

Note: This question is only possible because C++ is a very non-Pythonic language. "Explicit is better than implicit" after all. :)

Upvotes: 2

Views: 2896

Answers (3)

jww
jww

Reputation: 102225

Way to specify or determine which include header file a function comes from?

You usually do this when you are having trouble, like trying to figure out why a symbol is missing or where a header clash is occurring. Its not something you normally do at runtime as Lightness Races in Orbit and Bolov pointed out.

But if you want to do it, perform the following:

gcc -E t.c

If t.c is:

$ cat t.c
#include <stdio.h>

int main(int argc, char* argv[])
{
    return 0;
}

The output will be similar to:

$ gcc -E t.c
# 1 "t.c"
# 1 "<command-line>"
# 1 "t.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 323 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 324 "/usr/include/features.h" 2 3 4
# 356 "/usr/include/features.h" 3 4
...
# 866 "/usr/include/stdio.h" 3 4
extern FILE *popen (__const char *__command, __const char *__modes) ;
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 906 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 936 "/usr/include/stdio.h" 3 4

# 2 "t.c" 2

int main(int argc, char* argv[])
{
 return 0;
}

Then, pipe the output through grep to find the function of interest.

Upvotes: 2

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385104

E.g., is there a way to specify the sort function is from the <algorithm> header, and not the <iomanip> header, or whatever?

No. C++ as a compiled language (deliberately ignoring the preprocessor) has no knowledge of your headers' filenames, and as such they have nothing to do with the names of objects and types defined in headers.

If it helps, there is no std::sort in <iomanip>.

It's also kind of a strange thing to want to do. Overload resolution is performed by matching argument types, which is more than enough to disambiguate.

For instance, it would be cool if I could call sort using something like std::algorithm::sort instead of std::sort. There are so many headers built in to the standard library that just using std::* is not actually that informative, and tells me very little specifically about where * is coming from.

It doesn't matter. You don't need to know where it's coming from. The compiler doesn't need to know where it's coming from. It's completely irrelevant to actually using std::sort.

It is true that the C++ standard library does not organise its contents into many sub-namespaces, instead sticking with the top-level ::std for the most part. It could be argued that this makes coding with the standard library more of a mystery, but in fact it doesn't: it would only complicate look-up rules and make your life a lot more difficult when dealing with operator overloads, template instantiations and friends.

Ultimately I think it will be good coding practice to list the functions you will be using that are associated with each header:

#include <iostream>  //std::cout, std::cin

That way people can figure out what comes from where! Why is this not done more, given c++ community's admirable obsession with clarity about names?

While I do this for some POSIX/Linux sockets headers, so that I know which ones I can potentially remove in the future, I wouldn't do this for standard headers. The C++ community knows where std::cout is declared and if they forget then they can simply look it up.

Upvotes: 4

bolov
bolov

Reputation: 75688

I never heard of someone wanting something like this.

One thing you could do (it's tedious, so in my opinion it's not worth it) is to create yourself the namespaces and use using declarations in that namespace for each name that you want.

#include <iostream>

namespace iostream {
    using std::cout;
    using std::endl;
}

int main() {
    iostream::cout << 24 << iostream::endl;
    return 0;
}

My advice would be to not do it though. Just use them by they name only, and search the net each time you are not sure where they come from. With time, you will learn them without any effort.

Upvotes: 3

Related Questions