Use C11 static assert mechanism by default (#761, #766)

Hopefully this works better by default and is less confusing
when it doesn't. Added notes to migration document on how
to restore previous behavior.
diff --git a/docs/migration.md b/docs/migration.md
index 52711b5..f781276 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -31,6 +31,25 @@
 
 **Error indications:** "`protoc: Unknown flag: --nanopb_opt`"
 
+### `pb.h` uses C11 `_Static_assert` keyword by default
+
+**Rationale:** The nanopb generated headers use static assertions to catch
+errors at compile time. There are several mechanisms to implement this.
+The most widely supported is C11 `_Static_assert` keyword.
+Previously the code used negative size array definition trick, which is
+supported already in C99 but does not work with every compiler and can
+produce confusing error messages.
+
+**Changes:** Now `_Static_assert` is used by default. If preferred, the
+old default behavior can be restored by defining `PB_C99_STATIC_ASSERT`
+in `pb.h` or on compiler command line.
+
+**Required actions:** If the keyword is not recognized, set the compiler to
+C11 standard mode if available. If it is not available, define either `PB_C99_STATIC_ASSERT`
+or `PB_NO_STATIC_ASSERT`.
+
+**Error indications:** "`Undefined identifier _Static_assert`
+
 Nanopb-0.4.4 (2020-11-25)
 -------------------------
 
diff --git a/docs/reference.md b/docs/reference.md
index e378881..2d591ae 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -20,6 +20,8 @@
 * `PB_ENCODE_ARRAYS_UNPACKED`: Encode scalar arrays in the unpacked format, which takes up more space. Only to be used when the decoder on the receiving side cannot process packed arrays, such as [protobuf.js versions before 2020](https://github.com/protocolbuffers/protobuf/issues/1701).
 * `PB_CONVERT_DOUBLE_FLOAT`: Convert doubles to floats for platforms that do not support 64-bit `double` datatype. Mainly `AVR` processors.
 * `PB_VALIDATE_UTF8`: Check whether incoming strings are valid UTF-8 sequences. Adds a small performance and code size penalty.
+* `PB_C99_STATIC_ASSERT`: Use C99 style negative array trick for static assertions. For compilers that do not support C11 standard.
+* `PB_NO_STATIC_ASSERT`: Disable static assertions at compile time. Only for compilers with limited support of C standards.
 
 The `PB_MAX_REQUIRED_FIELDS` and `PB_FIELD_32BIT` settings allow
 raising some datatype limits to suit larger messages. Their need is
diff --git a/pb.h b/pb.h
index cc32546..644a759 100644
--- a/pb.h
+++ b/pb.h
@@ -165,14 +165,17 @@
 #    if defined(__ICCARM__)
        /* IAR has static_assert keyword but no _Static_assert */
 #      define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG);
-#    elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
-       /* C11 standard _Static_assert mechanism */
-#      define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG);
-#    else
+#    elif defined(PB_C99_STATIC_ASSERT)
        /* Classic negative-size-array static assert mechanism */
 #      define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
 #      define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
 #      define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER
+#    elif defined(__cplusplus)
+       /* C++11 standard static_assert mechanism */
+#      define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG);
+#    else
+       /* C11 standard _Static_assert mechanism */
+#      define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG);
 #    endif
 #  endif
 #else
diff --git a/tests/SConstruct b/tests/SConstruct
index 93b1ce9..b2b8b36 100644
--- a/tests/SConstruct
+++ b/tests/SConstruct
@@ -162,12 +162,13 @@
         
         # Debug info, warnings as errors
         env.Append(CFLAGS = '-g -Wall -Werror ')
-        env.Append(CORECFLAGS = '-Wextra')
+        env.Append(CORECFLAGS = '-Wextra ')
 
         # Pedantic ANSI C. On AVR this doesn't work because we use large
         # enums in some of the tests.
         if env.get("EMBEDDED") != "AVR":
-            env.Append(CFLAGS = '-ansi -pedantic')
+            env.Append(CFLAGS = '-ansi ')
+            env.Append(CORECFLAGS = '-pedantic ')
 
         # Profiling and coverage
         if not env.get("EMBEDDED"):
diff --git a/tests/cxx_descriptor/SConscript b/tests/cxx_descriptor/SConscript
index a11aff0..1b609b7 100644
--- a/tests/cxx_descriptor/SConscript
+++ b/tests/cxx_descriptor/SConscript
@@ -19,6 +19,9 @@
         print("Skipping {} test - compiler doesn't support it".format(std))
         continue
 
+    if std == 'c++03':
+        e.Append(CPPDEFINES = {'PB_C99_STATIC_ASSERT': 1})
+
     o1 = e.Object('message_descriptor_{}'.format(std), 'message_descriptor.cc')
     o2 = e.Object('message.pb_{}'.format(std), 'message.pb.c')
     p = e.Program([o1, o2])
diff --git a/tests/splint/splint.rc b/tests/splint/splint.rc
index 0cf4376..c01e2fc 100644
--- a/tests/splint/splint.rc
+++ b/tests/splint/splint.rc
@@ -36,3 +36,5 @@
 -noeffect
 -usedef
 
+# Splint doesn't support C11
+-DPB_C99_STATIC_ASSERT