gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > atoi()

#28156 - Krakken - Wed Oct 27, 2004 3:28 pm

Hi,

I can't seem to get atoi() or _atoi() to work. I have included stdlib.h. Is it unsupported? I don't see why it would be and it's got me very confused as to why it won't work.

I use DevKitARM, latest version.

Cheers,
Krakken.

#28161 - poslundc - Wed Oct 27, 2004 3:54 pm

Don't know if you can get atoi to work specifically... but a couple of thoughts:

1. Do you need it? There are very few GBA applications I can think of that need to parse a string into an integer.

2. You might consider just writing your own routine... for base 10, anyway, all it has to do is step through the string maintaining a running total. For each character, multiply the running total by ten, subtract '0' from the current char, and add it to your total. Repeat until you reach the end of the string or hit an illegal token (c < '0' || c > '9').

3. If you're looking to go the other way around (integer to string), which is a MUCH more common problem on the GBA, search the forum for keywords related to that or consider just using my posprintf.

Dan.

#28222 - Krakken - Thu Oct 28, 2004 12:21 am

Hi,

Thanks, poslundc.

Oops, it was itoa() silly me.

I wanted to see if I was making a silly mistake before considering writing my own. atoi allows you to set the base which was very convinent for what I needed. I am re-writing my entire library you see and i'm working on text display at the moment. The old way I used to do it with a printf() style interface added to much unnessacary code into my ROM and so it would increase the size 30 kb or so. This time I decided to go with a cleaner, cout style interface and wanted to be able to wrap up the entire integer conversion into one "operator << (int)" function.

I'll search around to see if someone has re-written the itoa() function and use that. Otherwise i'll use your posprintf() function.

Thanks,
Krakken.

#28225 - DekuTree64 - Thu Oct 28, 2004 12:38 am

There's a thread in the ASM section with various itoa implementations. Check out my one there using a reciprocal multiply (not my first post there using the BIOS div), it's pretty fast, and written in THUMB so no need to waste precious IWRAM on it since you most likely won't be spending much CPU time at all in it.
And yes, Dan's posprintf method is very fast too.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#28302 - Krakken - Fri Oct 29, 2004 11:01 am

For some reason i'm having trouble compiling with both bits of code. I keep getting undefined reference errors. I checked my makefile and all seems well. It's compiling the .s files and linking the .o files. Not sure what the problem is.

#28307 - poslundc - Fri Oct 29, 2004 12:39 pm

This indicates that you aren't linking correctly.

What are the parameters you are passing to GCC?

(Try changing about the order of posprintf and the program that uses it... doesn't always work, but it does sometimes.)

Dan.

#28309 - Krakken - Fri Oct 29, 2004 1:07 pm

Here ya go, I made it print out exactly what it is doing. I personally see no error.

arm-elf-gcc -specs=gba_mb.specs -mthumb-interwork -o _bin/rom.elf _bin/posprintf.o _bin/xGame.o _bin/xMain.o _bin/kFile.o _bin/kGBA.o _bin/kSRAM.o _bin/kText.o

I tried reversing the order putting posprintf.o at the end too but no luck.

All files are present in the "_bin" folder.

#28311 - poslundc - Fri Oct 29, 2004 1:49 pm

Hm... very strange. Can you print the exact errors that are being generated?

Also: it's a long shot, but maybe try adding ".section .text" to the first line of posprintf.S. I notice that I didn't specify a memory directive when looking at the code... it worked fine in Devkit Advance but perhaps is causing problems at the linking stage with Devkit ARM.

Dan.

#28357 - Krakken - Sat Oct 30, 2004 2:59 am

This is getting very strange now. Now I can't even seem to compile "posprintf.s". I haven't changed a thing in it (not even added the ".section .text" yet and it still gives me errors. Here is the command line that is generated by my makefile:


arm-elf-as kelix/external/posprintf.s -o _bin/posprintf.o


That gives me the errors:


kelix/external/posprintf.s: Assembler messages:
kelix/external/posprintf.s:0: Warning: end of file in comment; newline inserted
kelix/external/posprintf.s:1: Error: junk at end of line, first unrecognized character is `.'


The error I get if I try to link in the .o file:


_bin/xGame.o(.text+0x7e): In function `TEMPLATE::xGame::xGame()':
: undefined reference to `posprintf(char*, char const*, ...)'
_bin/xGame.o(.text+0x152): In function `TEMPLATE::xGame::xGame()':
: undefined reference to `posprintf(char*, char const*, ...)'


posprintf() is not in a namespace.

#28358 - poslundc - Sat Oct 30, 2004 3:22 am

The source file's extension should be a captial S, not a lowercase one, and you should run it through GCC rather than through GAS directly.

The captial-S indicates to GCC that it needs to run the preprocessor on it, and using GCC, uh, gives you access to the preprocessor.

In general, it is a good idea to call GCC on your files rather than specifying which component programs you want to use. Let GCC do the work for you; it usually knows what it's doing.

Dan.

#28365 - Krakken - Sat Oct 30, 2004 5:16 am

I actually originally did call GCC but changed it to AS thinking that may be the problem. Changing it to ".S" makes it compile fine now, thanks for that. The undefined error still persists after adding ".section .text" however.

#28368 - allenu - Sat Oct 30, 2004 6:30 am

Krakken wrote:
I actually originally did call GCC but changed it to AS thinking that may be the problem. Changing it to ".S" makes it compile fine now, thanks for that. The undefined error still persists after adding ".section .text" however.


I just gave it a shot myself out of curiousity. Try changing posprintf.h to this:

extern "C" void posprintf(char *, const char *, ...);

i.e. insert the "C" after extern. That works for me over here.

I suspect that your build of gcc is actually "g++" (the GNU C++ compiler) and so it is mangling the posprintf label for C++, thus making your linker not find it. This fixes it so that the C++ compiler treats posprintf() as a C function, and it does not mangle the function name.

#28370 - Krakken - Sat Oct 30, 2004 6:52 am

allenu wrote:
Krakken wrote:
I actually originally did call GCC but changed it to AS thinking that may be the problem. Changing it to ".S" makes it compile fine now, thanks for that. The undefined error still persists after adding ".section .text" however.


I just gave it a shot myself out of curiousity. Try changing posprintf.h to this:

extern "C" void posprintf(char *, const char *, ...);

i.e. insert the "C" after extern. That works for me over here.

I suspect that your build of gcc is actually "g++" (the GNU C++ compiler) and so it is mangling the posprintf label for C++, thus making your linker not find it. This fixes it so that the C++ compiler treats posprintf() as a C function, and it does not mangle the function name.


Thank you! You're a genius. :)

#28371 - Krakken - Sat Oct 30, 2004 7:00 am

Here, I fixed up the header. Now it should work for C and C++.

Code:
#ifdef __cplusplus
extern "C" void posprintf(char *, const char *, ...);
#else
extern void posprintf(char *, const char *, ...);
#endif


Cheers for everyones help. I appreciate it.

#28381 - poslundc - Sat Oct 30, 2004 3:17 pm

allenu wrote:
I just gave it a shot myself out of curiousity. Try changing posprintf.h to this:

extern "C" void posprintf(char *, const char *, ...);

i.e. insert the "C" after extern. That works for me over here.

I suspect that your build of gcc is actually "g++" (the GNU C++ compiler) and so it is mangling the posprintf label for C++, thus making your linker not find it. This fixes it so that the C++ compiler treats posprintf() as a C function, and it does not mangle the function name.


Ah, that's interesting. I'd never tried compiling it in the C++ environment. Good to know for the future!

Dan.

#28420 - Krakken - Sun Oct 31, 2004 5:30 am

Any ideas why I get a warning: no newline at end of file on both the posprintf header and .S file? I checked and both have a new line.

#28430 - allenu - Sun Oct 31, 2004 9:22 am

Krakken wrote:
Any ideas why I get a warning: no newline at end of file on both the posprintf header and .S file? I checked and both have a new line.


Perhaps your editor is not placing a carriage-return/line-feed combination at the end of the line, but is placing just a line-feed? I dunno.

#28450 - Miked0801 - Sun Oct 31, 2004 8:44 pm

I got this with newer versions of GCC. Older versions don't care what the last char of a file is, the newer ones do. Kind of a silly warning...

#28485 - tepples - Mon Nov 01, 2004 6:15 am

Over successive versions, GCC tends to get stricter with respect to standards conformance because too many people run into bugs trying to support programs that work both on GCC and on proprietary compilers. GCC warns you to save time when porting to platforms that treat it as an error rather than a warning.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#28487 - Krakken - Mon Nov 01, 2004 9:00 am

allenu wrote:
Krakken wrote:
Any ideas why I get a warning: no newline at end of file on both the posprintf header and .S file? I checked and both have a new line.


Perhaps your editor is not placing a carriage-return/line-feed combination at the end of the line, but is placing just a line-feed? I dunno.


Problem solved, it was as you said. I opened it in notepad to see if it was the file formatting (a good way to tell this) and there were no newlines.

Thanks.