minor atoi bug

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I stumbled onto:

atoi("v10") == 10

The repository shows the assembler version of atoi is correct but my version of avr-libc incorrectly checks the string for 'v' instead of '\v' (vertical tab 0xb).

Sorry if this is a known problem but my searching did not reveal anything.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought atoi() converted digits until it found the first non-numeric. As such I'd have thought atoi("v10") should be 0 as the conversion should terminate on the first character??

I don't have my reference books handy to check this. But if it returns 10 then it sounds like something might be wrong.

Cliff

EDIT: this: http://www.cplusplus.com/referen... and specifically "If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed" seems to confirm my understanding

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

atoi("v10") should be zero but returns 10 for me.

Also, atoi("\v10") should return 10 but returns zero for me.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well this is curious. The code that performs atoi() does this (amongst other things):

+0000005C:   9121        LD      R18,Z+           
+0000005D:   2322        TST     R18              
+0000005E:   F0F1        BREQ    PC+0x1F          
+0000005F:   3220        CPI     R18,0x20         
+00000060:   F3D9        BREQ    PC-0x04          
+00000061:   3029        CPI     R18,0x09         
+00000062:   F3C9        BREQ    PC-0x06          
+00000063:   302A        CPI     R18,0x0A         
+00000064:   F3B9        BREQ    PC-0x08          
+00000065:   302C        CPI     R18,0x0C         
+00000066:   F3A9        BREQ    PC-0x0A          
+00000067:   302D        CPI     R18,0x0D         
+00000068:   F399        BREQ    PC-0x0C          
+00000069:   3726        CPI     R18,0x76         
+0000006A:   F389        BREQ    PC-0x0E          
+0000006B:   322B        CPI     R18,0x2B         
+0000006C:   F019        BREQ    PC+0x04          
+0000006D:   322D        CPI     R18,0x2D         
+0000006E:   F421        BRNE    PC+0x05     

It's comparing characters in the string against all the "usual suspects" such as space, tab, line feed etc but notice that compare with 0x76 - it's specifically looking for a lower case 'v' and treating it as the other "white space" characters??

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since the assembler source I saw correctly performs the comparison on \v then it seems likely that there is either a problem with the assembler itself or a different source file was used.

The vertical tab character is probably pretty unusual so missing that whitespace is not a huge deal. But counting the lower case v as whitespace might be more problematic.

Further, if the assembler has a problem then this incorrect behavior may be present in other routines and libraries.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

atol appears to have the same problem:

PUSH r17
MOVW r30,r24
EOR r25,r25
EOR r24,r24
EOR r23,r23
EOR r22,r22
BCLR 6
LD r17, Z+
TST r17
BREQ 32
CPI r17, 0x20
BREQ -4
CPI r17, 0x9
BREQ -6
CPI r17, 0xa
BREQ -8
CPI r17, 0xc
BREQ -10
CPI r17, 0xd
BREQ -12
CPI r17, 0x76

An assembler anomaly I guess.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is not a problem with the assembler but with the code itself.
There is no known escape sequence for '\v' for the assembler.

Please file a bug report with the avr-libc project.

AFAICT only atoi.S and atol.S are affected. The code in ctype.S
explicitly uses hexadecimal numbers rather than escape characters.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.