3

I've always thought that if you do #include <cheader> (where header is some standard c++ header like stdio/stdlib/string), it is the same that #include <header.h>, but wrapped into the std namespace. How does that code snippet compiles then (g++ 4.7.3)?

#include <cstdlib>
int main()
{
    malloc(1);
    return 0;
}

Why should one include <cstdio> then (instead of <stdio.h>) if standard C functions will be in the global namespace anyway?

And the second question is — what should I do to get some of these functions out of the global namespace (while using c++ headers at the same time)? For instance, I don't want malloc to be in the global namespace since I have a home assignment : to write my own memory allocator (in particular, malloc and free functions) which I will compile into dynamic library and plug into any program using LD_PRELOAD.

karlicoss
  • 2,501
  • 4
  • 25
  • 29
  • 1
    Because, unfortunately, implementations are *allowed* to have the names outside of the `std::` namespace, as well as *required* to have them inside it. – juanchopanza May 27 '13 at 11:13
  • @juanchopanza but what's the point of using namespace `std` if we allow standard headers to clutter up the global namespace? – karlicoss May 27 '13 at 11:15
  • @karlicoss exactly! That is why I consider it "unfortunate". It only applies to names that come from the standard C library. All standard C++ functions and types are exclusively in the `std::` namespace. – juanchopanza May 27 '13 at 11:19
  • Also http://stackoverflow.com/q/8734230/166749 – Fred Foo May 27 '13 at 11:30

1 Answers1

4

How does that code snippet compiles then (g++ 4.7.3)?

Because 17.6.1.2/4 of the C++11 Standard specifies:

[...] It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

Therefore, implementations are allowed to define those entities in the global namespace.

Why should one include then (instead of ) if standard C functions will be in the global namespace anyway?

First of all, as a matter of good style. Including <stdio.h> gives you the certainty that all the entities are defined in the global namespace, while including <cstdio> gives you the certainty that those entities are where you want (in the std namespace), with the possible (but not certain) unwanted drawback that those names may appear in the global namespace too.

what should I do to get some of these functions out of the global namespace (while using c++ headers at the same time)?

Unfortunately, you cannot get an entity out of the namespace it lives in. But what you can do (apart from cursing at your implementation) is to avoid using Standard C functions altogether, and prefer using functions from the C++ Standard Library. Those are guaranteed to live in the std namespace.

So for instance, if you have to perform low-level memory management, use the new operator instead of malloc. Also, mind the emphasis on "have to": most of the time, you should use RAII wrappers such as smart pointers or standard containers to avoid having to cope with low-level memory management, new, and delete at all.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Yeah, I would certainly use the `new` operator, RAII and other stuff if I had to write some c++ application. However, I have to write the memory allocator, which other programs (binaries, like `gcc` or `vim` or whatever) will use. I can use only very low-level memory abstractions like `mmap` system call in that assignment. – karlicoss May 27 '13 at 11:27
  • @karlicoss: I'm not sure I understand why you cannot use the `new` operator; especially I'm not sure I understand this part: "* I have to write the memory allocator, which other programs (binaries, like gcc or vim or whatever) will use*". But well, I don't need to understand, as long as you know what you're doing ;) Anyway the moral of the story is: you can't take an entity out of the namespace it's declared in, but you *should* hope that your implementation will declare them in the `std` namespace. If it doesn't... well, at least you did your part an included the right headers. – Andy Prowl May 27 '13 at 11:31
  • because `new` and `delete` are still high level memory abstractions for this home assignment. Well, I have to implement a memory management library (with `malloc`, `free`, `calloc`, etc.), basically, I have to implement [heap](http://en.wikipedia.org/wiki/Heap_(programming)) myself. Then I'll run something like `LD_PRELOAD=myallocator.so some_program` and that program will use my memory allocator instead of the one provided by `g++`. – karlicoss May 27 '13 at 11:39