Hi!
I was writing simple userspace code that prints the values from the
struct statx the line in question looks like:
printf("%" PRIu64 "\n", st.stx_size);
This unexpectedly gives me warning on x86_64:
warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type '__u64' {aka 'long long unsigned int'}
Digging into the issue I've found that include/asm-generic/types.h looks like:
#ifndef _ASM_GENERIC_TYPES_H
#define _ASM_GENERIC_TYPES_H
/*
* int-ll64 is used everywhere now.
*/
#include <asm-generic/int-ll64.h>
#endif /* _ASM_GENERIC_TYPES_H */
Which is the cause why you cannot print __u64 with PRIu64 and would
force every userspace code to explicitly cast any __u64 in order to get
rid warnings. I would say that it would be better to fix the headers so
that __u64 has the same type as uint64_t so that PRIu64 could be then
used to print __u64 as well.
--
Cyril Hrubis
chrubis@suse.cz
* Cyril Hrubis:
Hi!
I was writing simple userspace code that prints the values from the
struct statx the line in question looks like:
printf("%" PRIu64 "\n", st.stx_size);
This unexpectedly gives me warning on x86_64:
warning: format '%lu' expects argument of type 'long unsigned int', but argument 5 has type '__u64' {aka 'long long unsigned int'}
The correct format depends on whether you use struct statx from the
glibc headers or the Linux UAPI headers. glibc uses uint64_t, Linux
uses __u64. uint64_t in glibc prefers unsigned long if the type is
64-bit, Linux uses unsigned long long unconditionally.
One solution is to use %ju and cast to (uintmax_t). Other cast-based
approaches are possible as well.
I'm not happy with the situation because those casts reduce type safety
and may suppress relevant compiler warnings.
Thanks,
Florian
Hi!
The correct format depends on whether you use struct statx from the
glibc headers or the Linux UAPI headers. glibc uses uint64_t, Linux
uses __u64. uint64_t in glibc prefers unsigned long if the type is
64-bit, Linux uses unsigned long long unconditionally.
One solution is to use %ju and cast to (uintmax_t). Other cast-based
approaches are possible as well.
I'm not happy with the situation because those casts reduce type safety
and may suppress relevant compiler warnings.
I still do not get why can't the kernel __u64 match the uint64_t at
least in userspace. It should be as easy as:
diff --git a/include/uapi/asm-generic/types.h b/include/uapi/asm-generic/types.h
index dfaa50d99d8f..3c9a1fc5d5c3 100644
--- a/include/uapi/asm-generic/types.h
+++ b/include/uapi/asm-generic/types.h
@@ -2,8 +2,12 @@
#ifndef _ASM_GENERIC_TYPES_H
#define _ASM_GENERIC_TYPES_H
/*
- * int-ll64 is used everywhere now.
+ * int-ll64 is used everywhere in kernel now.
*/
-#include <asm-generic/int-ll64.h>
+#if __BITS_PER_LONG == 64 && !__KERNEL__
+# include <asm-generic/int-l64.h>
+#else
+# include <asm-generic/int-ll64.h>
+#if
#endif /* _ASM_GENERIC_TYPES_H */
--
Cyril Hrubis
chrubis@suse.cz