Hello,
This might come off as pedantic but I'd like to bring this to your attention in 
case it's been overlooked.

POSIX and the Single UNIX Specification reserves names ending in "_t" to the 
implementation for use in any header. The provision is at 
https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_16_02_02
 but by "implementation" it means the operating system, or in our particular 
case it would be whatever C standard library one is using such as the GNU C 
Library. When an application defines an identifier that's reserved for the 
system to define, the behavior is undefined (except for certain special 
exceptions that don't apply here). This affects most of the client data types 
in gps.h.

If gpsd relies on undefined behavior in its operation, as many applications do, 
that'd be one thing. The reason why this specifically matters to me is because 
*client applications* need to be written to use the 'struct gps_data_t' and 
like data types, and therefore the namespace issue is viral: I must repeat the 
mistake in my application in order to use libgps. Because it's a type name it's 
not like it can be worked around with tricks like linker options or dlopen().

Fortunately I have an idea to solve this without too much pain. For the gps.h 
header used by libgps client applications, the use of the '_t' suffix could be 
kept by default but switched off with an include guard. For example a program I 
write could #define something like 'GPSD_POSIXLY_CORRECT' before including 
<gps.h>, so that when I do include <gps.h>, it can do an '#ifdef 
GPSD_POSIXLY_CORRECT' and define the same name without the _t suffix. This 
would let existing applications keep doing what they're doing without any 
difference, and because it's just the name of the structure type itself there's 
no ABI change.

There are a lot of similar issues but it'd be better for a regular gpsd 
contributor to decide what to do about those. Here are some random examples 
from gps.h:
• #define _GPSD_GPS_H_ — use of an underscore and a capital letter as a prefix 
is always reserved by the ISO C standard, even on freestanding systems or when 
no headers are included
• #define GPS_PATH_MAX, GPS_JSON_COMMAND_MAX — names ending in "_MAX" or "_MIN" 
are reserved for the system limits.h header which gps.h always includes; 
removing the underscores would solve this though
• typedef struct timespec timespec_t — this type name is very generic and would 
clash with any other library that does the same, or if the system defines this 
type for you already (and because it's reserved to the implementation that's 
allowed—GNU often defines convenience names like this such as "sighandler_t")

Unrelated remark:
> struct attitude_t {
>       ⋮
>       // arbitrary time tag (see UBX-ESF-MEAS), 32 bit unsigned
>       unsigned long timeTag;
>       ⋮
> }
Modern GNU/Linux systems with a 64-bit word size make long 64 bits; this 
indirectly comes from a POSIX requirement. It would be nice if, for embedded 
applications or systems that don't have a pre-existing libgps that would have 
its ABI broken, if this could use uint32_t instead.

I recognize that these problems may not be a priority for fixing and it's not 
my intention to "voluntell" anyone what to do about them. With this mail I hope 
to ensure those choices are informed ones.

Thanks,
John

P.S. A motivation for caring about this is I'm considering using gpsd on a 
microcontroller with a real-time operating system like NuttX or RTEMS and 
conformance to software standards when practical, and in the absence of a 
reason to depart from them, will make esoteric use cases like mine more likely 
to work without too much trouble. I'm making a navigation system for my bicycle 
🚲

Attachment: signature.asc
Description: This is a digitally signed message part

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to