26

This answer and it's multitude of duplicates indicate that I should be using #include <c*> for the C headers that I pull from in C++ code, and that I should be calling them with std::*.

I have been doing that but I notice an exception. std::assert doesn't seem to be defined, even when I correctly #include <cassert>.

What's going on here? Is this an implementation oversight, or an actual exception?

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 8
    `assert` is a [macro](http://en.cppreference.com/w/cpp/error/assert) – smac89 May 09 '16 at 19:46
  • 1
    `assert` is most likely implemented as a macro which cannot be used in namespace (because it doesn't produce language identifier like inline function does) – myaut May 09 '16 at 19:46
  • @CaptainObvlious Thanks for the link, that's the only official piece of information thus far. – Jonathan Mee May 09 '16 at 19:50
  • 1
    Perhaps you will find equal surprise in `stdout`, `errno`, `offsetof` and `va_start`? – Kerrek SB May 09 '16 at 19:52
  • 1
    I could never understand the value of this functionality. All funny things with invalidated variants usually happen in optimized code - and this is exactly when assert is suppressed. I am not following it. – SergeyA May 09 '16 at 19:53
  • 6
    @SergeyA Have you never tested your code ... ever? – Barry May 09 '16 at 19:54
  • @Barry, I am always testing my code. Spend more time testing it rather than writing, thanks for asking. However, I am not sure how it is relevant to run-time `assert`. – SergeyA May 09 '16 at 19:55
  • 2
    @SergeyA: I am with you on this one. Functionality that stops doing things when you are in production. So completely different behavior for production and debug code. If something is only going to go wrong while testing and not in production then you have some exceptional code. O hey wait we have something for exception situations. – Martin York May 09 '16 at 19:58
  • 7
    @SergeyA: There's value in it to people who find your assertion *"All funny things with invalidated variants usually happen in optimized code"* to be false. – Benjamin Lindley May 09 '16 at 20:00
  • @SergeyA There is nothing preventing you using *assert* on optimized code. – Galik May 09 '16 at 20:53
  • @Galik I mean you'd need to disable the `NDEBUG` define... If your using Visual Studio's standard implementation that define is used to cull out all kinds of sub optimal behavior... so yeah, there kinda is something stopping you from using `assert` on optimized code. – Jonathan Mee May 10 '16 at 03:48
  • What happened to reading [the documentation](http://en.cppreference.com/w/cpp/error/assert)? – Lightness Races in Orbit May 10 '16 at 15:16
  • @LightnessRacesinOrbit To be honest I knew that `assert` was a macro, but it wasn't until getting responses on this bug that I realized that a macro was not scoped by namespace. I thought it was. So... nothing happened to reading the documentation, I read it as normal, it was just a lack of understanding of macros that inspired this question. – Jonathan Mee May 10 '16 at 15:48
  • 1
    @JonathanMee Macros are handled by the C preprocessor (basically an automated copy/paste tool, at least when it comes to macros), and thus aren't there anymore by the time the code gets to the compiler. Unless the macro directly expands to a function or class, there's nothing that could even conceivably go in a namespace; if it does expand to one of those, then what it expands into can go in a namespace, but [it itself will have been removed before we get there](http://coliru.stacked-crooked.com/a/a20b8a55ec1633dd). – Justin Time - Reinstate Monica Jun 01 '17 at 00:20
  • @JustinTime Right, I understand macros, I just didn't know that this *was* a macro. I wonder, are there any other macros in the library that I have as of yet failed to discover? – Jonathan Mee Jun 01 '17 at 12:08
  • @JonathanMee Ah, okay. I'm not sure, actually; I'm not aware of any other function-like macros in the standard library, but it's possible that some compilers might inadvertently let a few from their C standard libraries link through. – Justin Time - Reinstate Monica Jun 04 '17 at 16:25
  • @JustinTime I'd be interested in seeing if there are any other macros that function similarly, if for no other reason just so I don't make this mistake again. I've asked about it here: https://stackoverflow.com/q/44369648/2642059 – Jonathan Mee Jun 05 '17 at 13:09
  • A macro such as `assert` is converted into C++ source code by the preprocessor, not the compiler. This is a step which is done before the compiler. That's why it cannot be in a namespace as the others suggested. – Galaxy Nov 22 '18 at 04:48
  • @Galaxy Yeah, I actually never thought about standard stuff being implemented by macros when I asked this question. Interestingly there are several other standard macros as well: https://stackoverflow.com/q/44369648/2642059 – Jonathan Mee Nov 25 '18 at 14:16

2 Answers2

30

assert is a macro, not a function. Hence, it needs to be used with plain old assert(condition).

Here's a supporting link: http://en.cppreference.com/w/cpp/error/assert.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Just thought a supporting link might be helpful here: http://en.cppreference.com/w/cpp/error/assert – Jonathan Mee May 10 '16 at 12:57
  • 3
    For reference: The C++17 standard lists this in chapter 20.5.1.2 paragraph 5 (`[headers]`): "Names which are defined as macros in C shall be defined as macros in the C ++ standard library [...]" – doak Mar 19 '19 at 10:47
16

assert is a macro, thus it isn't possible to restrict it to a namespace.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299