83

I've seen some information about differences between things like iostream vs iostream.h. From what I gathered from those the difference between them is that the version without the .h extension will not populate the namespace while the version with the extension will.

Is this the same for cmath vs math.h? Why is cmath (and many other files like it) prefixed with a c instead of just being math? Are there more differences between them?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
golmschenk
  • 11,736
  • 20
  • 78
  • 137
  • 1
    See also http://stackoverflow.com/q/2118422 and http://stackoverflow.com/q/2587445 for related (but maybe not dupe) questions. – Michael Burr May 22 '12 at 00:41

4 Answers4

40

I've seen some information about differences between things like iostream vs iostream.h.

[iostream.h] is not a standard header.

it is not an example of the issue you're raising.

[cmath] defines symbols in the std namespace, and may also define symbols in the global namespace. [math.h] defines symbols in the global namespace, and may also define symbols in the std namespace. if you include the former and use an unqualified symbol, it may compile with one compiler but not with another. therefore it's a good idea to use [math.h]. and in general, for such header pairs, to use the [.h] version.

c++98 provided a formal guarantee of the cxxx header not polluting the global namespace. maybe that was why they were defined. however, that was a bit harder to implement than polluting ones, so in practice no standard library implementation that i know of followed the standard in this respect, and so it was finally changed to reflect reality in c++11.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 23
    `therefore it's a good idea to use [math.h]. and in general, for such header pairs, to use the [.h] version.` I would disagree. The only reason the .h versions exist is for compatibility. The C headers are listed under [**depr**.c.headers] for a reason. – Jesse Good May 22 '12 at 00:32
  • 19
    @Jesse: the argument goes that if you include `math.h`, then you *know* you're dropping a heap of junk in your global namespace. If you include `cmath` then you *may or may not* be dropping a heap of junk in your global namespace. Conversely, you don't care whether or not you drop a heap of junk in namepace `std`, since you never define symbols in there yourself anyway. So the uncertainty about what `math.h` does is in some sense better than the uncertainty about what `cmath` does, regardless of what the committee thinks about it. – Steve Jessop May 22 '12 at 01:00
  • @SteveJessop: I see the difference. However, I would argue that rules are rules, and everyone should either abide by them or change the rules. – Jesse Good May 22 '12 at 01:57
  • 1
    @Jesse: whose rules? Deprecated doesn't mean "you can't use it". In the standard it's defined to mean the feature might not be present in the next standard. In English it means "disapproved", not "forbidden". As it turns out, even non-deprecated features might not be present in the next standard (`export` and sundry other breaking changes from C++03 to C++11). Self-styled C++03 implementations *should* have conformed to the standard, but the fact was, you knew that `#include ` triggered non-conforming behavior. If you have a rule not to use deprecated features, that doesn't affect Alf. – Steve Jessop May 22 '12 at 02:04
  • 2
    Ultimately, the standard definitively says what you're *allowed* to write, and also takes a view what's *wise* to write. There's no rule to say that the committee is always wise, even if it usually is, and fundamentally those headers are a messy compromise between different kinds of badness. Personally I use `cmath` and hope not to write a bug that my implementation doesn't catch (which is a conformance failure in C++03 and a QoI issue in C++11), but other people have different priorities. – Steve Jessop May 22 '12 at 02:08
  • @Steve: I think so but I'm not sure. I was not aware that EDG did standard library stuff. I thought only compiler stuff. I could ask Daveed. Should I? – Cheers and hth. - Alf May 22 '12 at 05:18
  • @Alf: not if it's any trouble. I didn't realise that EDG left the libraries to the individual compiler-packager (or whatever the proper term is for someone who uses EDG to create a compiler), so possibly it was a silly question. I'll check Comeau for myself later. – Steve Jessop May 22 '12 at 09:09
  • 10
    5 years later I'm sitting here wondering if I should be using `cmath` or `math.h`header for my C++ (11) program. Which one is it? From the popularity of this answers and some of the comments, I take it I should be using `math.h`? – birgersp Oct 18 '17 at 08:21
  • @gromit: I would recommend using both. Some pure C++ math stuff has now been added to only ``. It's trivial but some work to define wrapper headers for all the C headers, that include both variants. If you don't want to do it yourself you can use the wrappers in my [*stdlib* library over at GitHub](https://github.com/alf-p-steinbach/stdlib). – Cheers and hth. - Alf Oct 18 '17 at 10:11
  • 4
    Pretty bad advise, `` is deprecated in the C++ standard as of C++11, meaning compilers only support it for backwards compatibility. This means that you have no guarantees of what each implementation puts in the `x.h` headers since they aren't standard. In fact, it has been observed in some cases that the `x.h` versions sometimes have different contents to the `cx` versions on some implementations, where the overloads behaved differently which is potentially surprising. So always use the `` headers if you are writing C++. – themeeman Oct 20 '20 at 12:00
9

Maybe this would be helpful :

The C++ library includes the same definitions as the C language library organized in the same structure of header files, with the following differences:

1 - Each header file has the same name as the C language version but with a "c" prefix and no extension. For example, the C++ equivalent for the C language header file < stdlib.h > is < cstdlib>.

2 - Every element of the library is defined within the std namespace.

c-prefixed vs .h extension headers

Community
  • 1
  • 1
Hani Shams
  • 331
  • 3
  • 5
3

The headers whose names start with c are derived from the headers of the C standard library. The corresponding headers with the c prefix removed and a .h suffix added are identical (or very nearly identical) to the C standard library headers.

<cmath> defines the relevant symbols under the std namespace; <math.h> defines them globally.

(I just learned it's not quite that simple; see Alf's answer.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 3
    -1 no, the headers that start with `c` are C++ specific variants of C standard library headers. they do not come from the C library. also, there is no guarantee that `cmath` doesn't define the symbols in the global namespace, and there's no guarantee that `math.h` doesn't define the symbols in the `std` namespace. – Cheers and hth. - Alf May 22 '12 at 00:21
  • 1
    @Cheersandhth.-Alf: Sloppy wording on my part; I didn't mean "from the C standard library" to imply that they're *directly* from the C standard library. I didn't know that `` could define global symbols and `` could define symbols in the `std` namespace. Now that I know, I'm confused; why does the C++ standard leave that implementation-defined? – Keith Thompson May 22 '12 at 01:50
  • @KeithThompson: because it reflects reality. Lots of standard library implementations have done it for such a long time. Instead of forcing implementations to be more strict about this issue (experience shows this hasn't worked out quite as well as it could have), the standard committee relaxed programmers' expectations. – André Caron May 22 '12 at 01:58
  • @AndréCaron: I see this is explained in the questions linked from the comment on this question. I find this disappointing. – Keith Thompson May 22 '12 at 02:03
  • @Keith: I think a lot of people found it disappointing, but not disappointing enough to fix (for example) GCC. Since you've only just found out, maybe you'll be the person with the drive to submit that patch ;-) The original C++ standard had a view that turned out to be unreasonably optimistic, that C++ would be implemented independently of C. It turns out that everyone (lazily?) included the C libraries, whereas they should have done it by (for example) including implementation-specific underscore-underscore versions of the C libraries. – Steve Jessop May 22 '12 at 02:15
  • https://www.youtube.com/watch?v=j84pZM840eI&list=PLHTh1InhhwT7J5jl4vAhO1WvGHUUFgUQH&index=7 – Miguel Carvajal Sep 28 '16 at 17:00
  • 1
    @krvajal: That's a 69-minute video of a panel discussion the C++ standard library. Do you have a summary that will fit in a comment? – Keith Thompson Sep 28 '16 at 17:09
3

<cmath> and any <cxxx> header are standard C++, meaning you have strong guarantees of what is supported in those headers and how the functions in them work, as outlined in the C++ Standard. They define a series of functions in the std namespace, and that's it.

<math.h> and any <xxx.h> headers are not standard C++, despite being supported on every major implementation. However, since they are deprecated, there is no guarantee of what is inside those headers when you include them on your implementation. In fact, it has been observed on certain implementations that they provide functions that behave differently to the <cxxx> versions.

Therefore, you should always use <cxxx> when writing C++, and qualify the names of the functions with std::, for example std::malloc.

themeeman
  • 429
  • 5
  • 6