Skip to contentSkip to conversation

"Writing" instead of "Warning" in dlopen(3) manpage

DISCUSSION [email protected] 3 participants 9 messages Dec 31, 2013 – Jan 3, 2014 7 messages not in the archive Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#1 lore raw
Quoted 6 lines · On Tuesday 31 December 2013 07:42:09 [email protected]…

dlopen C code example contains following comment:

/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
   ... */

"Writing:" should be replaced with "Warning:".

both are correct

however, i wonder if the comment should be inverted. the latest POSIX spec requires that the natural cast work.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07

Linux man pages document the normal Linux environment, and that means POSIX, not strict ISO C.
-mike

#3 lore raw
In reply to a message not in the archive
Quoted 8 lines · Mike Frysinger
Quoted 6 lines · On Tuesday 31 December 2013 07:42:09 [email protected]…

dlopen C code example contains following comment:

/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
   ... */

"Writing:" should be replaced with "Warning:".

Quoted 8 lines

both are correct

however, i wonder if the comment should be inverted. the latest POSIX spec requires that the natural cast work.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07

Linux man pages document the normal Linux environment, and that means POSIX, not strict ISO C.

Thanks for your comments Mike. It's been at the back of my mind for a while now to do something about this. I applied the patch below. Look okay to you?

Cheers,

Michael

man3/dlopen.3 +15 -8
index dd54120..47ca55f 100644
@@ -466,15 +466,22 @@ main(int argc, char **argv)
 
     dlerror();    /* Clear any existing error */
 
-    /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
-       would seem more natural, but the C99 standard leaves
-       casting from "void *" to a function pointer undefined.
-       The assignment used below is the POSIX.1\-2003 (Technical
-       Corrigendum 1) workaround; see the Rationale for the
-       POSIX specification of dlsym(). */
+    cosine = (double (*)(double)) dlsym(handle, "cos");
 
-    *(void **) (&cosine) = dlsym(handle, "cos");
-.\" But in fact "gcc -O2 -Wall" will complain about the preceding cast.
+    /* According to the C99 standard, casting 'void *' to a function pointer
+       as shown above is forbidden. POSIX.1-2003 and POSIX.2008 followed
+       C99's requirement, and proposed the following workaround:
+
+           *(void **) (&cosine) = dlsym(handle, "cos");
+
+       This (clumsy) cast conforms with C99 and will avoid any compiler 
+       warnings.
+
+       The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a. POSIX.1-2013)
+       improved matters by requiring that conforming implementations support
+       casting 'void *' to a function pointer. Nevertheless, some compilers
+       (e.g., gcc with the '-pedantic' option) may complain about the cast
+       used in this program. */
 
 
 
Signature · 7 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw
In reply to a message not in the archive
Quoted 6 lines · On Wednesday 01 January 2014 20:46:59 Michael Kerrisk (man-pages) wrote:
man3/dlopen.3 +0 -0

/* According to the C99 standard, casting 'void *' to a function pointer as shown above is forbidden. POSIX.1-2003 and POSIX.2008 followed C99's requirement, and proposed the following workaround:

i don't want to be pedantic, buuuuut:
- you want to say "ISO C" rather than "C99"
- the spec says that it is "undefined behavior" rather than "forbidden"

i wonder about deleting the "followed C99's requirement" part. they aren't really following the requirement since (at least 2008) says that it must be supported.

the "POSIX.2008" probably should be "POSIX.1-2008". or maybe just change it to "POSIX.1" ?

man3/dlopen.3 main(int argc, char **argv) · line 478

Quoted 4 lines
man3/dlopen.3 +4 -0
+           *(void **) (&cosine) = dlsym(handle, "cos");
+
+       This (clumsy) cast conforms with C99 and will avoid any compiler
+       warnings.

might it be worth suggesting a union too ?

	double (*cosine)(double);
	union {
		void *vptr;
		double (*ptr)(double);
	} cast;
	cast.vptr = dlsym(...);
	cosine = cast.double;

i think this also avoids aliasing warnings and works nicely in C++ ? or i could be making this up entirely :).

Quoted 3 lines

The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a. POSIX.1-2013) improved matters by requiring that conforming implementations support casting 'void *' to a function pointer.

how about adding a comment inside of the man page itself linking to the POSIX pages ? making it visible to end users might be too much, but for people maintaining the comments (i.e. you) would be good.
http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html#tag_03_112_08
http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07

Quoted 3 lines

Nevertheless, some compilers
(e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */

three things:
- i think the ISO C standard is required to at least emit a warning
- i was going to suggest the -pedantic thing :)
- seriously, you're using "e.g." after chastising me ? :D
-mike

#7 lore raw
In reply to a message not in the archive

Hi Mike,

Thanks for following up.

Quoted 10 lines · Mike Frysinger
Quoted 6 lines · On Wednesday 01 January 2014 20:46:59 Michael Kerrisk (man-pages) wrote:
man3/dlopen.3 +0 -0

/* According to the C99 standard, casting 'void *' to a function pointer as shown above is forbidden. POSIX.1-2003 and POSIX.2008 followed C99's requirement, and proposed the following workaround:

i don't want to be pedantic, buuuuut:
- you want to say "ISO C" rather than "C99"

Yes, good point. Fixed now.

Quoted 1 line

- the spec says that it is "undefined behavior" rather than "forbidden"

Likewise; fixed now.

Quoted 3 lines

i wonder about deleting the "followed C99's requirement" part. they aren't really following the requirement since (at least 2008) says that it must be supported.

Yes, the language could be better. I changed it to "[they] accepted this state of affairs"

Quoted 2 lines

the "POSIX.2008" probably should be "POSIX.1-2008". or maybe just change it to "POSIX.1" ?

POSIX.1-2008.

Quoted 5 lines

man3/dlopen.3 main(int argc, char **argv) · line 478

Quoted 4 lines
man3/dlopen.3 +4 -0
+           *(void **) (&cosine) = dlsym(handle, "cos");
+
+       This (clumsy) cast conforms with C99 and will avoid any compiler
+       warnings.
Quoted 8 lines

might it be worth suggesting a union too ?

        double (*cosine)(double);
        union {
                void *vptr;
                double (*ptr)(double);
        } cast;
        cast.vptr = dlsym(...);
        cosine = cast.double;

I think I'll not worry about this.

Quoted 7 lines

i think this also avoids aliasing warnings and works nicely in C++ ? or i could be making this up entirely :).

Quoted 3 lines

The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a. POSIX.1-2013) improved matters by requiring that conforming implementations support casting 'void *' to a function pointer.

Quoted 5 lines

how about adding a comment inside of the man page itself linking to the POSIX pages ? making it visible to end users might be too much, but for people maintaining the comments (i.e. you) would be good.
http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html#tag_03_112_08
http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07

Yes, good idea.

Quoted 6 lines
Quoted 3 lines

Nevertheless, some compilers
(e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */

three things:
- i think the ISO C standard is required to at least emit a warning

Yes, but it's not quite clear to me if the POSIX.1-2013 is meaning that compilers should not issue a warning in this case. Maybe I'm misunderstanding something, though.

Quoted 2 lines

- i was going to suggest the -pedantic thing :)
- seriously, you're using "e.g." after chastising me ? :D

I don't recall chastising you as such... But, in running text using "e.g." and "i.e." often does not work well, I find (and most style manuals agree). As I said, mostly the only place you'll find these forms in the man pages is in parenthetical asides, as is done here.

Cheers,

Michael

Signature · 7 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#9 lore raw
In reply to a message not in the archive
Quoted 6 lines · On Thursday 02 January 2014 04:33:30 Michael Kerrisk (man-pages) wrote:
Quoted 5 lines · Mike Frysinger
Quoted 3 lines · On Wednesday 01 January 2014 20:46:59 Michael Kerrisk (man-pages) wrote:

Nevertheless, some compilers
(e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */

Quoted 6 lines
Quoted 2 lines

three things:
- i think the ISO C standard is required to at least emit a warning

Yes, but it's not quite clear to me if the POSIX.1-2013 is meaning that compilers should not issue a warning in this case. Maybe I'm misunderstanding something, though.

true. in this particular case, it's probably not worth being super pedantic since we covered our bases earlier on.

overall question: should the new comment block live above or below the example call ? it's currently below, but i kind of favor putting it before. i know as the content flows, the current one makes a bit of sense (show the right answer, and then as an aside, mention the portability issue), but the comment is specifically covering this line, so putting it above the line it is discussing is a bit more standard i think in the coding world. -mike

#11 lore raw
In reply to a message not in the archive

Hi Mike,

Quoted 17 lines · Mike Frysinger
Quoted 6 lines · On Thursday 02 January 2014 04:33:30 Michael Kerrisk (man-pages) wrote:
Quoted 5 lines · Mike Frysinger
Quoted 3 lines · On Wednesday 01 January 2014 20:46:59 Michael Kerrisk (man-pages) wrote:

Nevertheless, some compilers
(e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */

Quoted 6 lines
Quoted 2 lines

three things:
- i think the ISO C standard is required to at least emit a warning

Yes, but it's not quite clear to me if the POSIX.1-2013 is meaning that compilers should not issue a warning in this case. Maybe I'm misunderstanding something, though.

true. in this particular case, it's probably not worth being super pedantic since we covered our bases earlier on.

Quoted 6 lines

overall question: should the new comment block live above or below the example call ? it's currently below, but i kind of favor putting it before. i know as the content flows, the current one makes a bit of sense (show the right answer, and then as an aside, mention the portability issue), but the comment is specifically covering this line, so putting it above the line it is discussing is a bit more standard i think in the coding world.

I kind of prefer it as an aside, following the code, but I've now also added some words to more explicitly indicate that the comment refers to the code above it.

Cheers,

Michael

cosine = (double (*)(double)) dlsym(handle, "cos");

/* According to the ISO C standard, casting between function
pointers and 'void *', as done above, produces undefined results. POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround:

*(void **) (&cosine) = dlsym(handle, "cos");

This (clumsy) cast conforms with ISO C standard and will avoid any compiler warnings.

The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a. POSIX.1-2013) improved matters by requiring that conforming implementations support casting 'void *' to a function pointer. Nevertheless, some compilers (e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */

Signature · 7 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#13 lore raw
In reply to a message not in the archive
Quoted 9 lines · On Thursday 02 January 2014 14:20:50 Michael Kerrisk (man-pages) wrote:

/* According to the ISO C standard, casting between function
pointers and 'void *', as done above, produces undefined results. POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround:

*(void **) (&cosine) = dlsym(handle, "cos");

This (clumsy) cast conforms with ISO C standard and will avoid any compiler warnings.

"with the ISO C standard"

Quoted 2 lines
       The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a.
       POSIX.1-2013)

i thought you wanted to avoid "a.k.a." ? or does that not apply to parenthetical asides too ?

should all these random preferences be added in man-pages(7) ? off the top of my head:
- userspace vs user space vs user-space
- a.k.a. / e.g. / i.e. usage
- NUL usage (or lack thereof)
- HISTORY should be a .SS of NOTES
- wrapping based on periods/commas
- preference for 75 cols

some of these could even be checks added to scripts/ ... -mike

#15 lore raw
In reply to a message not in the archive
Quoted 6 lines · Mike Frysinger
Quoted 5 lines · On Thursday 02 January 2014 14:20:50 Michael Kerrisk (man-pages) wrote:

/* According to the ISO C standard, casting between function
pointers and 'void *', as done above, produces undefined results. POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround:

Quoted 6 lines
Quoted 4 lines

*(void **) (&cosine) = dlsym(handle, "cos");

This (clumsy) cast conforms with ISO C standard and will avoid any compiler warnings.

"with the ISO C standard"

Thanks.

Quoted 6 lines
Quoted 2 lines
       The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a.
       POSIX.1-2013)

i thought you wanted to avoid "a.k.a." ? or does that not apply to parenthetical asides too ?

Quoted 8 lines

should all these random preferences be added in man-pages(7) ? off the top of my head:
- userspace vs user space vs user-space
- a.k.a. / e.g. / i.e. usage
- NUL usage (or lack thereof)
- HISTORY should be a .SS of NOTES
- wrapping based on periods/commas
- preference for 75 cols

It's one of those things that's been on my TODO list for an age. I've made a start now, by creating a STYLE GUIDE section in man-page(7).

Quoted 1 line

some of these could even be checks added to scripts/ ...

Yes, one day...

Cheers,

Michael

Signature · 7 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html