Issue relating to SCN{d,u}FAST{8,16} macros in inttypes.h

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Issue relating to SCN{d,u}FAST{8,16} macros in inttypes.h

Andreas Kusalananda Kähäri-4
>Synopsis: SCNuFASTx and SCNdFASTx macros from inttypes.h does not work for x < 32
>Category: user
>Environment:
        System      : OpenBSD 6.4
        Details     : OpenBSD 6.4-current (GENERIC.MP) #462: Wed Nov 21 22:23:22 MST 2018
                         [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:

When using scanf() to read a value into a uint_fast8_t or uint_fast16_t
variable (or the signed equivalent), there is a mismatch between the
type of the variable and the format specification that the corresponding
SCN{u,d}FAST{8,16} macro expands to.

This seems to affect the {u,}int_fast{8,16}_t types and not the "least"
variant or ordinary {u,}int{8,16}_t types.

This gives rise to warnings from clang, and also affects the values that
are stored in the variables (see below).

The actual warning from clang (see code further down too):

prog.c:16:19: warning: format specifies type 'unsigned short *' but the argument has type 'uint_fast16_t *' (aka 'unsigned int *') [-Wformat]
              &a, &b, &c) != 3) {
                  ^~
prog.c:16:23: warning: format specifies type 'unsigned char *' but the argument has type 'uint_fast8_t *' (aka 'unsigned int *') [-Wformat]
              &a, &b, &c) != 3) {
                      ^~
2 warnings generated.

>How-To-Repeat:

Compile the below program using "cc -std=c99 prog.c"

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
    uint_fast32_t a;
    uint_fast16_t b;
    uint_fast8_t c;

    if (scanf("%" SCNuFAST32
              " %" SCNuFAST16
              " %" SCNuFAST8,
              &a, &b, &c) != 3) {
        fputs("Failed in scanf\n", stderr);
        exit(EXIT_FAILURE);
    }

    printf("a\t= %" PRIuFAST32 "\n", a);
    printf("b\t= %" PRIuFAST16 "\n", b);
    printf("c\t= %" PRIuFAST8 "\n", c);

    return EXIT_SUCCESS;
}

Note also that the b value (uint_fast16_t) is read incorrectly:

$ echo "1 2 3" | ./a.out
a = 1
b = 1324285954
c = 3

Also note that using the signed types int_fast{8,16}_t and the
SCNdFAST{8,16}, the same issue is present, and additionally, the c value
(int_fast8_t) is read incorrectly if negative (but not if a positive
value is entered):

$ echo "-1 -2 -3" | ./a.out
a = -1
b = -1450967042
c = 253

I'd be very happy to have errors in my code relating to the use of the
SCN macros pointed out to me.

>Fix:

Unknown.

dmesg:
OpenBSD 6.4-current (GENERIC.MP) #462: Wed Nov 21 22:23:22 MST 2018
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 4278124544 (4079MB)
avail mem = 4139184128 (3947MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.5 @ 0xe1000 (10 entries)
bios0: vendor innotek GmbH version "VirtualBox" date 12/01/2006
bios0: innotek GmbH VirtualBox
acpi0 at bios0: rev 2
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP APIC SSDT
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz, 3512.37 MHz, 06-3c-03
cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,RDRAND,NXE,RDTSCP,LONG,LAHF,ABM,ITSC,FSGSBASE,AVX2,INVPCID,L1DF,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: CPU supports MTRRs but not enabled by BIOS
cpu0: apic clock running at 1010MHz
cpu1 at mainbus0: apid 1 (application processor)
cpu1: Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz, 3224.88 MHz, 06-3c-03
cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,RDRAND,NXE,RDTSCP,LONG,LAHF,ABM,ITSC,FSGSBASE,AVX2,INVPCID,L1DF,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 0, core 1, package 0
ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 24 pins, remapped
acpiprt0 at acpi0: bus 0 (PCI0)
acpicpu0 at acpi0: C1(@1 halt!)
acpicpu1 at acpi0: C1(@1 halt!)
acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
acpiac0 at acpi0: AC unit online
acpivideo0 at acpi0: GFX0
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371AB IDE" rev 0x01: DMA, channel 0 configured to compatibility, channel 1 configured to compatibility
wd0 at pciide0 channel 0 drive 0: <VBOX HARDDISK>
wd0: 128-sector PIO, LBA, 102400MB, 209715200 sectors
atapiscsi0 at pciide0 channel 0 drive 1
scsibus1 at atapiscsi0: 2 targets
cd0 at scsibus1 targ 0 lun 0: <VBOX, CD-ROM, 1.0> ATAPI 5/cdrom removable
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
cd0(pciide0:0:1): using PIO mode 4, Ultra-DMA mode 2
wd1 at pciide0 channel 1 drive 0: <VBOX HARDDISK>
wd1: 128-sector PIO, LBA, 5120MB, 10485760 sectors
wd1(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 2
vga1 at pci0 dev 2 function 0 "InnoTek VirtualBox Graphics Adapter" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
virtio0 at pci0 dev 3 function 0 "Qumranet Virtio Network" rev 0x00
vio0 at virtio0: address 08:00:27:4c:c3:b6
virtio0: apic 2 int 19
"InnoTek VirtualBox Guest Service" rev 0x00 at pci0 dev 4 function 0 not configured
piixpm0 at pci0 dev 7 function 0 "Intel 82371AB Power" rev 0x08: apic 2 int 23
iic0 at piixpm0
virtio1 at pci0 dev 8 function 0 "Qumranet Virtio Network" rev 0x00
vio1 at virtio1: address 08:00:27:56:79:c2
virtio1: apic 2 int 16
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
root on wd0a (411f6d6665fa8a05.a) swap on wd0b dump on wd0b

usbdevs:
usbdevs: no USB controllers found
--
Andreas Kusalananda Kähäri,
National Bioinformatics Infrastructure Sweden (NBIS),
Uppsala University, Sweden.

Reply | Threaded
Open this post in threaded view
|

Re: Issue relating to SCN{d,u}FAST{8,16} macros in inttypes.h

Philip Guenther
On Thu, 22 Nov 2018, Andreas Kusalananda Kähäri wrote:

> >Description:
> When using scanf() to read a value into a uint_fast8_t or uint_fast16_t
> variable (or the signed equivalent), there is a mismatch between the
> type of the variable and the format specification that the corresponding
> SCN{u,d}FAST{8,16} macro expands to.
>
> This seems to affect the {u,}int_fast{8,16}_t types and not the "least"
> variant or ordinary {u,}int{8,16}_t types.
>
> This gives rise to warnings from clang, and also affects the values that
> are stored in the variables (see below).

Your code looks correct to me; <inttypes.h> seems incorrect.

oks for the diff below?


Philip Guenther


Index: inttypes.h
===================================================================
RCS file: /data/src/openbsd/src/include/inttypes.h,v
retrieving revision 1.11
diff -u -p -r1.11 inttypes.h
--- inttypes.h 11 Jun 2013 15:59:16 -0000 1.11
+++ inttypes.h 22 Nov 2018 17:53:05 -0000
@@ -162,8 +162,8 @@
 #define SCNdLEAST32 "d" /* int_least32_t */
 #define SCNdLEAST64 "lld" /* int_least64_t */
 
-#define SCNdFAST8 "hhd" /* int_fast8_t */
-#define SCNdFAST16 "hd" /* int_fast16_t */
+#define SCNdFAST8 "d" /* int_fast8_t */
+#define SCNdFAST16 "d" /* int_fast16_t */
 #define SCNdFAST32 "d" /* int_fast32_t */
 #define SCNdFAST64 "lld" /* int_fast64_t */
 
@@ -180,8 +180,8 @@
 #define SCNiLEAST32 "i" /* int_least32_t */
 #define SCNiLEAST64 "lli" /* int_least64_t */
 
-#define SCNiFAST8 "hhi" /* int_fast8_t */
-#define SCNiFAST16 "hi" /* int_fast16_t */
+#define SCNiFAST8 "i" /* int_fast8_t */
+#define SCNiFAST16 "i" /* int_fast16_t */
 #define SCNiFAST32 "i" /* int_fast32_t */
 #define SCNiFAST64 "lli" /* int_fast64_t */
 
@@ -199,8 +199,8 @@
 #define SCNoLEAST32 "o" /* uint_least32_t */
 #define SCNoLEAST64 "llo" /* uint_least64_t */
 
-#define SCNoFAST8 "hho" /* uint_fast8_t */
-#define SCNoFAST16 "ho" /* uint_fast16_t */
+#define SCNoFAST8 "o" /* uint_fast8_t */
+#define SCNoFAST16 "o" /* uint_fast16_t */
 #define SCNoFAST32 "o" /* uint_fast32_t */
 #define SCNoFAST64 "llo" /* uint_fast64_t */
 
@@ -217,8 +217,8 @@
 #define SCNuLEAST32 "u" /* uint_least32_t */
 #define SCNuLEAST64 "llu" /* uint_least64_t */
 
-#define SCNuFAST8 "hhu" /* uint_fast8_t */
-#define SCNuFAST16 "hu" /* uint_fast16_t */
+#define SCNuFAST8 "u" /* uint_fast8_t */
+#define SCNuFAST16 "u" /* uint_fast16_t */
 #define SCNuFAST32 "u" /* uint_fast32_t */
 #define SCNuFAST64 "llu" /* uint_fast64_t */
 
@@ -235,8 +235,8 @@
 #define SCNxLEAST32 "x" /* uint_least32_t */
 #define SCNxLEAST64 "llx" /* uint_least64_t */
 
-#define SCNxFAST8 "hhx" /* uint_fast8_t */
-#define SCNxFAST16 "hx" /* uint_fast16_t */
+#define SCNxFAST8 "x" /* uint_fast8_t */
+#define SCNxFAST16 "x" /* uint_fast16_t */
 #define SCNxFAST32 "x" /* uint_fast32_t */
 #define SCNxFAST64 "llx" /* uint_fast64_t */
 

Reply | Threaded
Open this post in threaded view
|

Re: Issue relating to SCN{d,u}FAST{8,16} macros in inttypes.h

Andreas Kusalananda Kähäri-4
On Thu, Nov 22, 2018 at 09:58:55AM -0800, Philip Guenther wrote:

> On Thu, 22 Nov 2018, Andreas Kusalananda Kähäri wrote:
> > >Description:
> > When using scanf() to read a value into a uint_fast8_t or uint_fast16_t
> > variable (or the signed equivalent), there is a mismatch between the
> > type of the variable and the format specification that the corresponding
> > SCN{u,d}FAST{8,16} macro expands to.
> >
> > This seems to affect the {u,}int_fast{8,16}_t types and not the "least"
> > variant or ordinary {u,}int{8,16}_t types.
> >
> > This gives rise to warnings from clang, and also affects the values that
> > are stored in the variables (see below).
>
> Your code looks correct to me; <inttypes.h> seems incorrect.
>
> oks for the diff below?
>
[cut]

I saw the patch go into the tree.
Much appreciated, thanks!

--
Andreas Kusalananda Kähäri,
National Bioinformatics Infrastructure Sweden (NBIS),
Uppsala University, Sweden.

Reply | Threaded
Open this post in threaded view
|

Re: Issue relating to SCN{d,u}FAST{8,16} macros in inttypes.h

Todd C. Miller-2
In reply to this post by Philip Guenther
On Thu, 22 Nov 2018 09:58:55 -0800, Philip Guenther wrote:

> Your code looks correct to me; <inttypes.h> seems incorrect.
>
> oks for the diff below?

Yes, this was a copy & pasto.  OK millert@

 - todd