Bona Fide OS Developer
View unanswered posts | View active topics It is currently Thu Mar 28, 2024 7:22 am



Post new topic Reply to topic  [ 30 posts ]  Go to page 1, 2, 3  Next
 problem with char* 
Author Message
Post 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

Joined: Wed Feb 10, 2010 6:32 am
Posts: 26
Post 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
Profile

Joined: Tue Jul 28, 2009 4:09 am
Posts: 58
Location: United Kingdom
Post 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.

Code:
puts("hello");


... 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
Profile

Joined: Wed Feb 10, 2010 6:32 am
Posts: 26
Post 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 :D

EDIT: Updated gcc now it works... sorry that I bothered you :) and thx


Wed Feb 10, 2010 10:01 am
Profile

Joined: Tue Jul 28, 2009 4:09 am
Posts: 58
Location: United Kingdom
Post 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
Profile

Joined: Wed Feb 10, 2010 6:32 am
Posts: 26
Post 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
Profile

Joined: Tue Jul 28, 2009 4:09 am
Posts: 58
Location: United Kingdom
Post 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
Profile

Joined: Wed Feb 10, 2010 6:32 am
Posts: 26
Post 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
Profile

Joined: Sat Jul 25, 2009 9:15 am
Posts: 257
Post 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
Profile

Joined: Sat Jul 25, 2009 9:15 am
Posts: 257
Post 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
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 30 posts ]  Go to page 1, 2, 3  Next


Who is online

Users browsing this forum: No registered users and 14 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

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin and tweaked by the BF Team.