Re: Compiler difference
From: Sam Sungshik Kong (ssk_at_chol.nospam.net)
Date: 08/27/04
- Previous message: Mike Wahler: "Re: Compiler difference"
- In reply to: Mike Wahler: "Re: Compiler difference"
- Next in thread: Mike Wahler: "Re: Compiler difference"
- Reply: Mike Wahler: "Re: Compiler difference"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 27 Aug 2004 19:00:21 GMT
Make, thanks for your reply.
>size_t void split(char* in_str, char* out_str[MAX_NUMBER], int* size_t)
About the style issue, I originally wanted to implement it like you said.
However, when I checked other examples of array and its size, they tend to
stick them together.
So I decided to keep them together.
I prefer your way though.
>String literals, by definition are not allowed to be
>modified. Attempts to do so result in 'undefined behavior'
The following is also string literal, right?
char s[] = "one;two;three;four;five;";
And it can be modified.
What's the difference between char* s and char s[]?
>char** t; //caused run time error and changed char* t[MAX_NUMBER]
> This creates a pointer, but doesn't give it a value (it doesn't
> point anywhere. Evalutating the value of this pointer will
> produce more undefined behavior.
t was meant to be an 'out' parameter.
That's why I didn't give it a value.
My wrong understanding...
Thanks.
Sam
"Mike Wahler" <mkwahler@mkwahler.net> wrote in message
news:p2LXc.213$8d1.46@newsread2.news.pas.earthlink.net...
>
> "Sam Sungshik Kong" <ssk@chol.nospam.net> wrote in message
> news:ObJXc.12342$UL3.12149@newssvr27.news.prodigy.com...
> > Hello group!
> >
> > I am a newbie to C.
> >
> > I wrote a string splitting code.
> > It compiled fine with Borland C++(5.3) and ran ok.
> > However, the very same code didn't compile with MS C++ for a reason, and
> > after modification, didn't run well for another reason.
> >
> > ----------------Original code----------------
> >
> > #include <stdio.h>
> > #include <string.h>
> >
> > #define MAX_NUMBER 20
> >
> > void split(char* in_str, char* out_str[MAX_NUMBER], int* length)
>
> The following is just a 'style' issue, not part
> of your problem.
>
> Why are you going to the trouble of a pointer
> argument in order to tell the caller the new
> 'length'? Why not just have the function return that
> value? Also, the 'length' should be type 'size_t'.
>
> size_t void split(char* in_str, char* out_str[MAX_NUMBER], int* size_t)
>
> Then call with e.g.:
> size_t result = 0
> result = split(s, t, &count);
>
> Your way will work, but imo it's unnecessary.
>
> I've addressed the real problems below.
>
> > {
> > char* sep = ";"; //delimiter
> > int count = 0;
> >
> > out_str[count] = strtok(in_str, sep);
> > while(out_str[count] != NULL)
> > {
> > count ++;
> > out_str[count] = strtok(NULL, sep);
> > }
> >
> > *length = count;
> > }
> >
> >
> >
> > int main()
> > {
> > char* s = "one;two;three;four;five;"; //later changed into char s[];
>
> This creates an unammed array of the characters
> "one;two;three;four;five;", creates a pointer,
> and initializes its value with the address of
> the first character of the array.
>
> String literals, by definition are not allowed to be
> modified. Attempts to do so result in 'undefined behavior'
> (which can mean anything from 'seems to work', to a
> horrible crash, or anything else.)
>
> > char** t; //caused run time error and changed char* t[MAX_NUMBER]
>
> This creates a pointer, but doesn't give it a value (it doesn't
> point anywhere. Evalutating the value of this pointer will
> produce more undefined behavior.
>
> > int count;
> >
> > split(s, t, &count);
> >
> > for (int i = 0; i < count; i ++)
> > {
> > printf(t[i]);
> > printf("\n");
> > }
> > }
> >
> > ----------Anticipated result----------
> > one
> > two
> > three
> > four
> > five
> > ------------------------------------
>
> One cannot accurately predict undefined behavior.
> Equally allowed output of your program (if any) would be
> "boogity boo!".
>
> >
> > I found out that strtok modifies the original string.
>
> Yes, it does.
>
> > Borland C++ allowed "char* s" to be modified but MS C++ didn't.
>
> The pointer can be validly modifed. What you've pointed it
> to is not (the string literal). The syntax rules don't
> prohibit it, but the result is specified as undefined.
> The compiler was not required (but not prohibited either)
> to reject the code.
>
> > I changed char* s into char s[] and it compiled with MS C++.
> >
> > Even after compilation with MS C++, this program caused an exception.
>
> Yes, the other problem was still there (using uninitialized
> object 't'.)
>
> > I changed char** t into char* t[MAX_NUMBER] and it became fine.
>
> Right. Because now 'strtok()' has somewhere to write to that
> is 'owned' by your program. Before it did not.
>
> > I guess this was my fault.
>
> Yup. :-)
>
> > But I wonder why the program compiled with Borland C++ didn't cause any
> > error.
>
> Your code had no diagnosable errors, just undefined behavior
> (which cannot always be diagnosed).
>
> Your best protection against such bugs is not to depend upon
> a compiler to report your mistakes, but to get a very good
> grasp of the language rules, and of course thoughtfulness
> and carefulness.
>
> -Mike
>
>
- Previous message: Mike Wahler: "Re: Compiler difference"
- In reply to: Mike Wahler: "Re: Compiler difference"
- Next in thread: Mike Wahler: "Re: Compiler difference"
- Reply: Mike Wahler: "Re: Compiler difference"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|