Author |
Message |
Guest
|
problem with char*
Hi, first of all I really like your page and it helps me a lot I have a short question, my problem is, that I always have to write "strings" like this: puts("hello\0"); and now I simply got to lazy to always write that leading zero... can anyone help me? my compilerflags are: gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o ....... this is my puts... void puts(unsigned char *text){ int i; for (i = 0; i < strlen(text); i++){ putch(text[i]); } } thanks in advance Sharpner
|
Wed Feb 10, 2010 6:43 am |
|
|
Sharpner
Joined: Wed Feb 10, 2010 6:32 am Posts: 26
|
Re: problem with char*
ok damn it, i wasn't logged in that sucks cause now I can't edit the post.. well, "leading" is wrong.. I meant the zero at the end of course xD Code: int strlen(const char *str) { int c = 0; while (*str++ != '\0') { c++; } return c; } that's my strlen method... I know that it simply counts till it reaches '\0' but I thought gcc would add this by default
|
Wed Feb 10, 2010 7:41 am |
|
|
Agalloch
Joined: Tue Jul 28, 2009 4:09 am Posts: 58 Location: United Kingdom
|
Re: problem with char*
Hey, The C++ Standard, and all implementation that I know of (including GCC) specify that any string formed using double quotation marks will have a NULL character to the end. ... will definetly create a 6 byte char array, ending with a NULL character and pass a pointer to it to the function "puts". It is therefore probable that your issue is elsewhere. What exactly is the error? And where abouts in your code does it occur? It would also be helpful to know the environment you are working in and whether all functions were written entirely by you. Also, there are some issues unrelated to your problem. You should not place a function call to retrieve unchanging data inside the loop condition. The optimizer for C++ will not be able to tell whether or not the result changes meaning it will call strlen for every iteration of the loop. It is also considered best practice to use the form "++i", not "i++" in the incremement expression of the loop. While they both produce the same results, the current implementation causes issues with the way in which the temporary result of the incrememt is stored. I did not look at them in detail, but I can't see any functional issues with the actual code you posted, so the errors are either elsewhere or I'm being slow today. Thanks, James
Last edited by Agalloch on Wed Feb 10, 2010 9:46 am, edited 1 time in total.
Tag fix
|
Wed Feb 10, 2010 9:45 am |
|
|
Sharpner
Joined: Wed Feb 10, 2010 6:32 am Posts: 26
|
Re: problem with char*
Thanks for your fast reply. You're right putting strlen in the loop is kinda dumb. But besides that... yeah I wrote everything by myself, I'm not far in my code so I really can't show much but at the moment my "kernel" boots, and I'm in a simple shell where I can enter commands etc... The strange thing is, when I don't put NULL at the end by hand, the compiled kernel is around 2mb and doesn't do anything.. it seems to me that my compiled kernel doesn't add NULL at the end and gets into an inifite loop... when I do it by hand my kernel is 16kb big... But I don't get why it matters wheter i use pre-increment or post-increment? well doesn't matter EDIT: Updated gcc now it works... sorry that I bothered you and thx
|
Wed Feb 10, 2010 10:01 am |
|
|
Agalloch
Joined: Tue Jul 28, 2009 4:09 am Posts: 58 Location: United Kingdom
|
Re: problem with char*
Hey,
That's extremely suprising, what version of GCC were you using and to what version have you moved?
My immediate thinking - as it caused compilation size differences - is that you haven't linked in a section from the object files, missing the ".rdata" section is extremely common and may cause other problems even if a more recent GCC avoids it for certain cases of implied null-terminated string.
Is your Operating System Open Source? I wouldn't mind having a look at the code sometime, though I am glad it works for the time! Good luck.
Though it is a small issue, I am a perfectionist, and the pre-increment does in theory cause a small increase in performance. When using post-increment, the original variable is updated, and a temporary variable is created. In a statement, this temporary variable replaces all "i" references, as the original value. In a loop, the increment is completed immediately, however a temporary value was created. In large loops, and loops that use objects as the increment this means creating a new variable (possibly a large one) on every iteration.
Thanks,
James
Last edited by Agalloch on Wed Feb 10, 2010 11:37 am, edited 1 time in total.
Better punctuate your sentences and never redact the name of anything ambiguous.
|
Wed Feb 10, 2010 11:35 am |
|
|
Sharpner
Joined: Wed Feb 10, 2010 6:32 am Posts: 26
|
Re: problem with char*
hi thanks for the explaination with the preincrement.. didn't know that, really surprised me... I now use gcc 4.4.3 but I updated so quickly that I don't remember which version I used before.. sorry Well it is not closed source, but I am only learning and so most of it is crap... I just started to recode what I now know gets more structured and clean... But thanks for your help, I'm sure I will be stuck again pretty soon xD As soon as I am not a little further I will make it public... But i really like this forum my ld looks like this: Code: phys = 0x00100000; SECTIONS { .text phys : AT(phys) { code = .; *(.text) *(.rodata) . = ALIGN(4096); } .data : AT(phys + (data - code)) { data = .; *(.data) . = ALIGN(4096); } .bss : AT(phys + (bss - code)) { bss = .; *(.bss) . = ALIGN(4096); } end = .; }
see anything wrong with it? bye Sharpner
|
Wed Feb 10, 2010 2:27 pm |
|
|
Agalloch
Joined: Tue Jul 28, 2009 4:09 am Posts: 58 Location: United Kingdom
|
Re: problem with char*
Hey,
I can very much relate. I am on my third rewrite since I moved from experimenting and learning the basics to attempting a real project (while still learning of course), and am currently writing the second design for this one. Rewriting can be a good thing when getting off your feet, but try not to let perfectionism get in the way of moving beyond the basic concepts. You don't want to get stuck improving a boot loader and never learn anything about more advanced concepts.
Your linker script is near identical to ones I've had working in the past, so I'm stumped for ideas unfortunately. I'm glad it worked!
Thanks,
James
|
Wed Feb 10, 2010 4:27 pm |
|
|
Sharpner
Joined: Wed Feb 10, 2010 6:32 am Posts: 26
|
Re: problem with char*
okay.. I'm back.... I started my recode and now I got the same damn problem again -.- I only thought it worked because fuckin' vim didn't show the \0 char... so the gcc upgrade didn't work either... any ideas? Code: void puts(string msg){ int8u i, length; length = strlen(msg); for(i = 0; i < length; i++){ putch(msg[i]); } } Code: void putch(int8u ch){ if(ch == '\n'){ csr_y++; csr_x = 0; }else{ textmemptr[csr_y*80+csr_x] = ch | (attrib << 8); csr_x++; if(csr_x >= 80){ csr_y++; csr_x = 0; } } move_csr(); } Code: int8u strlen(string msg){ int8u i = 0; while(msg[i] != '\0'){ i++; } return i; }
Code: typedef unsigned int int32u; //32 Bit - unsigned typedef int int32; //32 Bit - signed typedef unsigned short int16u; //16 Bit - unsigned typedef short int16; //32 Bit - signed typedef unsigned char int8u; // 8 Bit - unsigned typedef char int8; // 8 Bit - signed typedef int8* string;
Code: nasm -f aout -o bin/grub.o asm/grub.asm gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o bin/kernel.o init/kernel.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o bin/base.o lib/base.c gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o bin/vga.o driver/video/vga.c gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o bin/stringinfo.o lib/string/info.c ld -T link.ld -o bin/kernel bin/base.o bin/grub.o bin/kernel.o bin/vga.o bin/stringinfo.o
I think that is everything related to the code... hopefully you see something where I went wrong! thanks in Advance..
|
Fri Feb 12, 2010 6:11 am |
|
|
DudeOfX
Joined: Sat Jul 25, 2009 9:15 am Posts: 257
|
Re: problem with char*
describe the output... maybe its something else... have you used strings like? Code: puts("my string\0 invisible part"); in a situation like this, just to get an idea of whats happening I would start testing out the functions... I would test out strlen by overwriting it with a hardcoded length Code: length = strlen(msg); length = 5;
or hardcode the test expression inside the for loop in puts();
|
Fri Feb 12, 2010 10:06 am |
|
|
DudeOfX
Joined: Sat Jul 25, 2009 9:15 am Posts: 257
|
Re: problem with char*
you think gcc is using pascal strings where the first byte in the array determines the length of the array? I doubt it but I spend 30min looking for your bug and it looks clean to me?
|
Fri Feb 12, 2010 10:08 am |
|
|
Who is online |
Users browsing this forum: No registered users and 0 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|