Closed Bug 713531 Opened 14 years ago Closed 5 years ago

Investigate C11 _Static_assert compiler support, and make MOZ_STATIC_ASSERT expand to it when possible to do so without warnings

Categories

(Core :: MFBT, defect)

defect
Not set
minor

Tracking

()

RESOLVED WONTFIX

People

(Reporter: Waldo, Assigned: kylma, Mentored)

References

Details

(Keywords: good-first-bug, Whiteboard: [lang=c])

Attachments

(1 file, 2 obsolete files)

C++11 includes static_assert(cond, reason) syntax to implement static assertions. MOZ_STATIC_ASSERT expands to this in compilers that support it. C11 (the next edition of C) includes functionally identical _Static_assert syntax. Someone (not me) should investigate compiler support for _Static_assert -- particularly for when it can be used without triggering a warning (note that in my cursory investigation clang's docs may be wrong about it triggering a warning except in -std=c11 code, not sure if I'm misreading or either docs or code have a bug) -- and make MOZ_STATIC_ASSERT expand to it when possible.
Whiteboard: [good first bug][mentor=Waldo][lang=c]
Would like to take this up
After a bit of research, it looks like GCC and Clang support the _Static_assert macro, but MSVC does not. I have yet to test it in any compiler, so this is simply the result of an hour or so of searching.
I've gotten _Static_assert to run on Clang, but as I suspected, it does not appear to work in MSVC. GCC quits on a "not defined in this scope" error for both _Static_assert and static_assert. I suspect that this is due to a faulty GCC setup on Windows. I'm nearly a total newbie, so that's entirely likely. Additionally, could I be marked as the assignee of this bug?
Assignee: nobody → briguy92
Status: NEW → ASSIGNED
I haven't used Mercurial before, so I'm not sure if I created this patch correctly. Please let me know if it's messed up in any way.
I'll take a look at this shortly.
Flags: needinfo?(jwalden+bmo)
Hmm, this patch is indeed a bit weird. It looks like it applies to a file that has _Static_assert uses in it already. And it's reverting __GNUC__-conditioned _Static_assert uses to the current system for that compiler, that doesn't use _Static_assert. Maybe this is a diff against a patch you'd created, and not against an unmodified tree? I'd suggest asking on irc.mozilla.org in the #introduction channel for Mercurial help, to see if you can get realtime help creating a fully-properly-generated patch.
Flags: needinfo?(jwalden+bmo)
Brian, could you confirm that you're still working on this?
Flags: needinfo?(briguy92)
Yes, I am still working on this. I haven't had a chance to look at it in a while due to school, but will upload a new patch as soon as I can get my Mercurial setup figured out.
Flags: needinfo?(briguy92)
OK, I think that I need to throw this one back in the pool.
Assignee: briguy92 → nobody
Status: ASSIGNED → NEW
Mentor: jwalden+bmo
Whiteboard: [good first bug][mentor=Waldo][lang=c] → [good first bug][lang=c]
Assignee: nobody → kylma
Comment on attachment 8443926 [details] [diff] [review] Edited mtbf/Assertions.h to expand MOZ_STATIC_ASSERT to _Static_assert or static_assert with clang, gcc and MSC Review of attachment 8443926 [details] [diff] [review]: ----------------------------------------------------------------- ::: mfbt/Assertions.h @@ +99,5 @@ > +# endif > +# if __has_extension(c_static_assert) > +# define MOZ_STATIC_ASSERT(cond, reason) _Static_assert((cond), reason) > +# elif __has_extension(cxx_static_assert) > +# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) Given that we're in a !__cplusplus block, I think these two lines can/should be removed. @@ +108,5 @@ > +# elif defined(__GNUC__) > +# if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) > +# define MOZ_STATIC_ASSERT(cond, reason) _Static_assert((cond), reason) > +# elif MOZ_GCC_VERSION_AT_LEAST(4, 3, 0) > +# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) This too. @@ +114,5 @@ > +# define MOZ_STATIC_ASSERT(cond, reason) \ > + extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE > +# endif > +# elif defined(_MSC_VER) > +# if MSC_VER >= 1600 /* MSVC 10 */ _MSC_VER typo @@ +118,5 @@ > +# if MSC_VER >= 1600 /* MSVC 10 */ > +# define MOZ_STATIC_ASSERT(cond, reason) static_assert((cond), reason) > +# else > +# extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE > +# endif This bit was mis-indented -- should be # elif defined(_MSC_VER) # if _MSC_VER >= 1600 /* MSVC 10 */ # define MOZ_STATIC_ASSERT(cond, reason), static_assert((cond), reason) # else # extern void... # endif # elif defined(__COUNTER__)
Attachment #8443926 - Flags: review?(jwalden+bmo) → feedback+
Also: now that it's landed, please use MOZ_MSVC_VERSION_AT_LEAST() for the MSVC version check. So much more readable!
Does MSVC10+ support static_assert in C-mode?
I will update the patch as soon as I can. @emk: I found this http://msdn.microsoft.com/en-us/library/bb918086%28v=vs.90%29.aspx which seems to indicate that it does.
(In reply to Emma Benoit from comment #14) > I will update the patch as soon as I can. > > @emk: I found this > http://msdn.microsoft.com/en-us/library/bb918086%28v=vs.90%29.aspx which > seems to indicate that it does. I couldn't find any explanation from that MSDN article about neither C++99 static_assert nor C11 _Static_assert. The _STATIC_ASSERT macro uses a trick to implement static assertion for older compilers.
(In reply to Masatoshi Kimura [:emk] from comment #13) > Does MSVC10+ support static_assert in C-mode? MSVC10+ doesn't even support C-mode. :-) The C support they have is, as a matter of policy, largely incident to their support for C++. No reason to do anything for MSVC for this bug.
(In reply to Jeff Walden [:Waldo] (remove +bmo to email) from comment #16) > MSVC10+ doesn't even support C-mode. :-) It does. It will compile the source files with .c extension in C-mode. It also has the -TC option to force compile sources in C-mode. > The C support they have is, as a > matter of policy, largely incident to their support for C++. No reason to > do anything for MSVC for this bug. MSVC doesn't recognize the inline keyword in C-mode. I suspect the static_keyword is the same.
s/static_keyword/static_assert keyword/;
Updated, I removed the MSVC part.
Attachment #733566 - Attachment is obsolete: true
Attachment #8443926 - Attachment is obsolete: true
Attachment #8446150 - Flags: feedback?(jwalden+bmo)
Comment on attachment 8446150 [details] [diff] [review] mfbt/Assertions.h: expand MOZ_STATIC_ASSERT with clang and gcc Review of attachment 8446150 [details] [diff] [review]: ----------------------------------------------------------------- Looks reasonable. Make the one change and post for review, and I can land it for you. ::: mfbt/Assertions.h @@ +100,5 @@ > +# if __has_extension(c_static_assert) > +# define MOZ_STATIC_ASSERT(cond, reason) _Static_assert((cond), reason) > +# else > +# define MOZ_STATIC_ASSERT(cond, reason) \ > + extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE Rather than copy this version, please copy the __COUNTER__ version defined below. Also use it in the __GNUC__ case as well. Ideally we'd have this code fall through into the actual __COUNTER__ version below, but unfortunately this #if defined(TEST_MACRO) && MACRO_DEFINED_ONLY_IF_TEST_MACRO_DEFINED() doesn't short-circuit, because of how preprocessing works, so nesting and duplication like this is the most practical solution.
Attachment #8446150 - Flags: feedback?(jwalden+bmo) → feedback+
Keywords: good-first-bug
Whiteboard: [good first bug][lang=c] → [lang=c]

We removed MOZ_STATIC_ASSERT some time ago in favor of just using C++11 static_assert directly. And we don't really have that much pure C code at all any more (and where possible I try to push back on our adding any more), so there just isn't a need for this any more.

Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → WONTFIX

(In reply to Jeff Walden [:Waldo] from comment #21)

We removed MOZ_STATIC_ASSERT some time ago in favor of just using C++11 static_assert directly. And we don't really have that much pure C code at all any more (and where possible I try to push back on our adding any more), so there just isn't a need for this any more.

MOZ_STATIC_ASSERT is currently used only in libmar C code:

https://searchfox.org/mozilla-central/rev/fa2df28a49883612bd7af4dacd80cdfedcccd2f6/modules/libmar/src/mar.h#27

https://searchfox.org/mozilla-central/rev/fa2df28a49883612bd7af4dacd80cdfedcccd2f6/modules/libmar/src/mar_private.h#30-31,35-37

I have a patch to replace libmar's MOZ_STATIC_ASSERTs with static_assert (C11's macro #defined in assert.h as C11's _Static_assert keyword), but that requires compiling mozilla-central's C code as C11 instead of C99 (-std=gnu99). And that, unsurprisingly, opens more rat holes. I have a WIP on my back burner but no ETA.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: