aboutsummaryrefslogtreecommitdiffstats
path: root/doc/README.developer
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2021-12-15 21:28:02 +0000
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-12-16 04:59:04 +0000
commit06e6f7d922d9c2c3391269d250984b4a82be6a3f (patch)
treee909c1f3f256c91237ff07ca12b635f7b41d4cfa /doc/README.developer
parent606bc277772df2beec6e07e53cd35f6547b7f4d8 (diff)
Docs: First pass to update README.developer to C11
Update to reflect the transition from C99 to C11. Remove obsolete comments and recommendations. Add a bit about transitioning to C fixed width types. Related to #17768.
Diffstat (limited to 'doc/README.developer')
-rw-r--r--doc/README.developer92
1 files changed, 46 insertions, 46 deletions
diff --git a/doc/README.developer b/doc/README.developer
index 1811a89a1c..e17ed030df 100644
--- a/doc/README.developer
+++ b/doc/README.developer
@@ -65,39 +65,38 @@ Wireshark runs on many platforms, and can be compiled with a number of
different compilers; here are some rules for writing code that will work
on multiple platforms.
-In general, not all C99 features can be used since some C compilers used to
-compile Wireshark, such as Microsoft's C compiler, don't support all C99
-features. The C99 features that can be used are:
-
- - flexible array members
- - compound literals
- - designated initializers
- - "//" comments
- - mixed declarations and code
- - new block scopes for selection and iteration statements (that is, declaring
- the type in a for-loop like: for (int i = 0; i < n; i++) ;)
- - macros with a variable number of arguments (variadic macros)
- - trailing comma in enum declarations
- - inline functions (guaranteed only by use of glib.h)
+Building Wireshark requires a compiler that supports C11. This includes
+reasonably recent version of GCC and clang. Microsoft Visual Studio supports
+C11 from Visual Studio 2019 version 16.8 and later. Support requires an updated
+Universal C Runtime (UCRT) and Windows SDK version to work properly with the
+conforming preprocessor. The minimum SDK version is 10.0.20348.0 (version 2104).
+
+The C11 has some optional parts that are not a requirement to build Wireshark.
+In particular the following optional C11 features must NOT be used:
+ - Variable length arrays
+ - Bounds-checking interfaces (Annex K)
+
+We don't allow them because their value is questionable and requiring them
+would exclude a lot of compilers and runtimes that we wish to support.
Don't initialize global or static variables (variables with static
-storage duration) in their declaration with non-constant values. Not
-all compilers support this. E.g., if "i" is a static or global
+storage duration) in their declaration with non-constant values. This is not
+permitted in C. E.g., if "i" is a static or global
variable, don't declare "i" as
- guint32 i = somearray[2];
+ uint32_t i = somearray[2];
outside a function, or as
- static guint32 i = somearray[2];
+ static uint32_t i = somearray[2];
inside or outside a function, declare it as just
- guint32 i;
+ uint32_t i;
or
- static guint32 i;
+ static uint32_t i;
and later, in code, initialize it with
@@ -107,34 +106,27 @@ instead. Initializations of variables with automatic storage duration -
i.e., local variables - with non-constant values is permitted, so,
within a function
- guint32 i = somearray[2];
+ uint32_t i = somearray[2];
is allowed.
Don't use zero-length arrays as structure members, use flexible array members
instead.
-Don't use anonymous unions; not all compilers support them.
-Example:
-
- typedef struct foo {
- guint32 foo;
- union {
- guint32 foo_l;
- guint16 foo_s;
- } u; /* have a name here */
- } foo_t;
-
Don't use "uchar", "u_char", "ushort", "u_short", "uint", "u_int",
"ulong", "u_long" or "boolean"; they aren't defined on all platforms.
-If you want an 8-bit unsigned quantity, use "guint8"; if you want an
+Use the fixed width integers provided in C since C99. These are defined
+in <stdint.h>.
+
+If you want an 8-bit unsigned quantity, use "uint8_t"; if you want an
8-bit character value with the 8th bit not interpreted as a sign bit,
-use "guchar"; if you want a 16-bit unsigned quantity, use "guint16";
-if you want a 32-bit unsigned quantity, use "guint32"; and if you want
-an "int-sized" unsigned quantity, use "guint"; if you want a boolean,
-use "gboolean". Use "%d", "%u", "%x", and "%o" to print those types;
-don't use "%ld", "%lu", "%lx", or "%lo", as longs are 64 bits long on
-many platforms, but "guint32" is 32 bits long.
+use "unsigned char"; if you want a 16-bit unsigned quantity, use "uint16_t";
+if you want a 32-bit unsigned quantity, use "uint32_t"; and if you want
+an "int-sized" unsigned quantity, use "unsigned"; if you want a boolean,
+use "bool" (defined in <stdbool.h>). You don't need to explicitly include
+these headers; they are included in <wireshark.h>. Use that instead.
+
+To print fixed width integers you MUST use the macros provided in <inttypes.h>.
Don't use "long" to mean "signed 32-bit integer", and don't use
"unsigned long" to mean "unsigned 32-bit integer"; "long"s are 64 bits
@@ -144,7 +136,7 @@ long on many platforms. Use "gint32" for signed 32-bit integers and use
Don't use "long" to mean "signed 64-bit integer" and don't use "unsigned
long" to mean "unsigned 64-bit integer"; "long"s are 32 bits long on
many other platforms. Don't use "long long" or "unsigned long long",
-either, as not all platforms support them; use "gint64" or "guint64",
+either, as not all platforms support them; use "int64_t" or "uint64_t",
which will be defined as the appropriate types for 64-bit signed and
unsigned integers.
@@ -170,23 +162,29 @@ will have to cast to a compatible data type, e.g.
size_t i;
char greeting[] = "hello, sailor";
- guint byte_after_greet;
+ uint8_t byte_after_greet;
i = strlen(greeting);
- byte_after_greet = tvb_get_guint8(tvb, (gint) i); /* OK */
+ byte_after_greet = tvb_get_guint8(tvb, (int) i); /* OK */
or
- gint i;
+ int i;
char greeting[] = "hello, sailor";
- guint byte_after_greet;
+ uint8_t byte_after_greet;
- i = (gint) strlen(greeting);
+ i = (int) strlen(greeting);
byte_after_greet = tvb_get_guint8(tvb, i); /* OK */
See http://www.unix.org/version2/whatsnew/lp64_wp.html for more
information on the sizes of common types in different data models.
+A lot of legacy code still uses GLib types and I/O replacement API. These
+should be gradually transitioned to use the standard interfaces provided in
+C11. Sometimes it may be necessary to use an unsavory cast or two or abuse
+a macro to bridge the two codebases during the transition. Such is life,
+use your judgement and do the best possible under the circumstances.
+
When printing or displaying the values of 64-bit integral data types,
don't use "%lld", "%llu", "%llx", or "%llo" - not all platforms
support "%ll" for printing 64-bit integral data types. Instead, for
@@ -221,7 +219,8 @@ argument. You must do
call_routine2(xxx, format, ap);
va_end(ap);
-rather
+rather than
+
va_start(ap, format);
call_routine1(xxx, format, ap);
call_routine2(xxx, format, ap);
@@ -248,6 +247,7 @@ will not work with all compilers - you have to do
}
with some statement, even if it's a null statement, after the label.
+Preferably don't do it at all.
Don't use "bzero()", "bcopy()", or "bcmp()"; instead, use the ANSI C
routines