Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dcl.dcl] Consider using less awkward example to illustrate static_assert #1514

Closed
Eelis opened this issue Mar 5, 2017 · 18 comments
Closed
Assignees

Comments

@Eelis
Copy link
Contributor

Eelis commented Mar 5, 2017

[dcl.dcl]/6 uses the following example to demonstrate the use of static_assert:

static_assert(char(-1) < 0, "this library requires plain 'char' to be signed");

Perhaps this not the best example to use, since a test for signedness of char would probably be more idiomatically expressed using std::is_signed_v. Of course, since this is a core chapter, we may not want to use std::is_signed_v, but I suspect one could come up with an example static_assert that is illustrative, idiomatic, and does not use the stdlib.

@jensmaurer
Copy link
Member

I don't think we should use a library facility in the core language section unless necessary to show the issue.

I suspect one could come up with an example static_assert that is illustrative, idiomatic, and does not use the stdlib

Please make a concrete suggestion.

@Eelis
Copy link
Contributor Author

Eelis commented Mar 5, 2017

Fair enough, here are some ideas:

static_assert(__cplusplus >= 201703, "This library requires C++17 or newer.");

static_assert(sizeof(void*) == 8, "This library requires a 64 bit address space.");

static_assert(CHAR_BIT == 8, "This library requires 8-bit bytes.");

static_assert(__STDC_­HOSTED__, "This library requires a hosted implementation.");

@tkoeppe
Copy link
Contributor

tkoeppe commented Mar 5, 2017

What I find most offensive about the status quo is that it suggests that it's somehow OK to depend on the signedness of char. The standard should be neither tutorial nor encouragement of bad practices.

@jensmaurer
Copy link
Member

jensmaurer commented Mar 5, 2017

@Eelis:

static_assert(sizeof(void*) == 8, "This library requires a 64 bit address space.");

This is not a good check, since size(void*) = sizeof(char) = 1 would be possible on a 64-bit machine.

static_assert(CHAR_BIT == 8, "This library requires 8-bit bytes.");

That requires a #include.

@jensmaurer
Copy link
Member

jensmaurer commented Mar 5, 2017

@tkoeppe: It's as "OK" to depend on the signedness of "char" as it is to depend on sizeof(void*) == 8 or CHAR_BIT == 8. Sometimes, you want to check for it because your algorithm breaks down otherwise, and getting a clean error message is much preferable over a wrong answer at run-time.

@Eelis
Copy link
Contributor Author

Eelis commented Mar 5, 2017

@jensmaurer I see you responded to 2 of my 4 suggestions. How do you feel about the other 2?

@tkoeppe
Copy link
Contributor

tkoeppe commented Mar 6, 2017

@jensmaurer: Hm, I think all of those would be in equally poor taste. Something more innocuous would be static_assert(alignof(T) > N) or some such, provided that T and N are some parameters in scope.

@jensmaurer
Copy link
Member

@Eelis: I'm not fully convinced by the suggestions; and I remember CWG having trouble coming up with a plausible example, too.
@tkoeppe: "alignof" is very platform-dependent, so that seems somewhat strange, too.
(Don't get me wrong; I think all the examples presented will appear in real code (maybe even more so than the status quo), but they still all feel awkward.)

@Eelis
Copy link
Contributor Author

Eelis commented Mar 6, 2017

Coming up with something that's obviously better is certainly a harder challenge than I expected! :)

I also tried finding examples with github code search, but couldn't find anything that meets all the criteria.

I guess if this has already been tried without success before, and we're ready to give up, then this can be closed.

@AlisdairM
Copy link
Contributor

@jensmaurer I think platform-dependant assumptions are exactly what you would use static_assert for, outside of type/value-dependent contexts in templates.

@jensmaurer
Copy link
Member

@AlisdairM: I agree, so what's wrong with the status quo:
static_assert(char(-1) < 0, "this library requires plain 'char' to be signed");
It's an obviously platform-dependent assumption.

@tkoeppe
Copy link
Contributor

tkoeppe commented Mar 8, 2017

@jensmaurer: I've actually seen this exact thing in real code twice recently, and it was never appropriate :-(

Checks for sizes and alignments are fairly plausible, say, if you want to build a buffer to hold arbitrary elements that get placement-constructed in it later, where the purpose of the static assertion is more to prevent misuse than to constrain the platform.

@jensmaurer
Copy link
Member

@tkoeppe: Fine, but
static_assert(sizeof(int) == 4, "requires 32-bit integers"))
is a bad check, too. (Think char = 9 bits and int = 36 bits, or sizeof(short) == 1, yet sizeof(int) == 4.)
So, it seems checking CHAR_BIT is the only reasonable thing so far, except that it's a library macro :-(

@jwakely
Copy link
Member

jwakely commented Mar 9, 2017

255 == (unsigned char)-1 ?

@Eelis
Copy link
Contributor Author

Eelis commented Mar 9, 2017

@jwakely: That one has the same issue as the status quo, namely that it would be more idiomatically expressed using a library facility.

@AlisdairM
Copy link
Contributor

sizeof(int) == sizeof(void*)?
Lots of legacy code likes to make this (frequently bad) assumption, that could at least be checked and errored?

@jensmaurer
Copy link
Member

Yeah, let's try that.

@Eelis
Copy link
Contributor Author

Eelis commented Feb 23, 2018

Awesome, thanks guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants