Thread: Is this safe?

  1. #31
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So what happens when your typecast to an unsigned char, which was formerly EOF now is the letter 'a'?

    You're still missing my point: There is no reason at all to ever typecast. Check your values, then send it to the function. Don't mung it all up and force it there.


    Quzah.
    Hope is the first step on the road to disappointment.

  2. #32
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I give up. Keep reading the Torek piece until it makes sense. In there, you will find a reason to cast. On the Pfaff site, it is already stated that it's not an always-do kind of thing. But it has its place. So "no reason at all" is not the correct answer. Mine (I should say what I've gathered here and there) is more of "it depends".
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #33
    Geek. Cobras2's Avatar
    Join Date
    Mar 2002
    Location
    near Westlock, and hour north of Edmonton, Alberta, Canada
    Posts
    113
    Quote Originally Posted by quzah
    So what happens when your typecast to an unsigned char, which was formerly EOF now is the letter 'a'?

    You're still missing my point: There is no reason at all to ever typecast. Check your values, then send it to the function. Don't mung it all up and force it there.


    Quzah.

    So, basically, you are saying, do your own conversions if the data isn't in a good format, rather than trying to use a typecast?
    James G. Flewelling
    Rgistered Linux User #327359
    Athabasca University Student (BSc. CIS)

    http://catb.org/~esr/faqs/smart-questions.html
    http://catb.org/jargon/

    http://www.ebb.org/ungeek
    ---GEEK CODE---
    Version: 3.12
    GCS/IT/M d- s+:++ a-->->>+>++>+++>? C++++>$ UL++>++++$ P++>++++ L++>++++$
    E W++ N o? K? w++(--)>--- O? M? V? PS--(---) PE Y+ PGP? t 5? !X R(*)>++
    tv-->! b++(+++)>++++ DI? D+++(---)>++++$ G e*>++$ h++>*$ r!>+++ y?
    ----/GEEK CODE----
    upd: 2005-02-11

  4. #34
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Dave_Sinkula
    I give up. Keep reading the Torek piece until it makes sense. In there, you will find a reason to cast. On the Pfaff site, it is already stated that it's not an always-do kind of thing. But it has its place. So "no reason at all" is not the correct answer. Mine (I should say what I've gathered here and there) is more of "it depends".
    Of course there's no reason to cast. Why on earth shoud you? Check your data, and pass it over correctly.
    Code:
    if( c == EOF || (c >= 0 && c <= UCHAR_MAX ) )
        ...safe to use...
    else
        ...don't use...
    How on earth can it ever be "correct" to smash something into a cast and pass it to a function wich may now do something to that data that it shouldn't be?

    What happens if you smash some negative number in your stream into an unsigned char, and now it thinks it's an 'a', so it turns it into an 'A'?

    Um, hello? Wrong.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #35
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    What an entertaining discussion. I wonder how long it will take both sides to realize that the whole argument is pointless.
    My best code is written with the delete key.

  6. #36
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Feed this to itself.
    Code:
    #include <stdio.h>
    #include <limits.h>
    #include <ctype.h>
    
    int myisprint(int value)
    {
       if ( value < 0 )
       {
          puts("Bzzzt!");
          return 0;
       }
       return isprint(value);
    }
    
    /* embedded nasty character: ö */
    
    int main(void)
    {
       char buffer[1024];
       int i, j;
       for ( i = 0; i < 1024; ++i )
       {
          int c = getchar();
          if ( c == EOF )
          {
             break;
          }
          if ( c >= 0 && c <= UCHAR_MAX )
          {
             buffer[i] = c;
          }
       }
       for ( j = 0; j < i; ++j )
       {
    #if 1 /* avoid UB */
          if ( myisprint((unsigned char)buffer[j]) )
    #else /* invoke UB */
          if ( myisprint(buffer[j]) )
    #endif
          {
             /* putchar(buffer[j]); */
          }
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #37
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You're joking, right? You've already guarinteed that all values will fall into an unsigned char's range. Now you're trying to say "See, my cast works!". Of course it works! You just forced it to!
    Code:
    int main(void)
    {
       char buffer[1024];
       int i, j;
       for ( i = 0; i < 1024; ++i )
       {
          int c = getchar();
          if ( c == EOF )
          {
             break;
          }
          if ( c >= 0 && c <= UCHAR_MAX )
          {
             buffer[i] = c;
          }
       }
       for ( j = 0; j < i; ++j )
       {
    #if 1 /* avoid UB */
          if ( myisprint((unsigned char)buffer[j]) )
    Duh! You've just done what I've told you to do: Validate your data, and the cast is pointless.

    The only way it will ever not work is if your char is signed. In which case, you're still doing it wrong. Actually, you've already been "kind of" doing it right. You're just not fully doing the check. You're actually trying to make it look like you're doing the check correctly, when you're intentionally doing it wrong to prove your point. Because if you're going to complain about values less than zero, you should be checking for values above UCHAR_MAX as well. But in the end, your 'myisprint' is very close to what I've been saying all along: Check your work, and then pass it. Don't half ass it, do it right.
    Code:
    int davesisprint( int c )
    {
        if( c == EOF || ( c >= 0 && c <= UCHAR_MAX ) )
            return isprint( c );
        return 0;
    }
    Now why again do I need a cast here Dave? Oh, that's right, I don't.


    Prelude's commenting on us arguing "pointless" semantics? Pot meet kettle?


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #38
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    So you'd do this to avoid the cast?
    Code:
    #include <stdio.h>
    #include <limits.h>
    #include <ctype.h>
    
    /* embedded nasty character: ö */
    int main(void)
    {
       char buffer[1024];
       int i, j;
       for ( i = 0; i < 1024; ++i )
       {
          int c = getchar();
          if ( c == EOF )
          {
             break;
          }
          buffer[i] = c;
       }
       for ( j = 0; j < i; ++j )
       {
          if ( buffer[j] != EOF || (buffer[j] >= 0 && buffer[j] <= UCHAR_MAX) && 
              isprint(buffer[j]))
          {
             /* putchar(buffer[j]); */
          }
       }
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #39
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Prelude's commenting on us arguing "pointless" semantics? Pot meet kettle?
    I'm allowed to be hypocritical because I'm also irrational.
    My best code is written with the delete key.

  10. #40
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So how about passing it a valid value instead of -10? -10 is not a valid passable value as you yourself have stated. If you want unsigned characters, use them. If you want signed characters, use those. Don't try and make one pretend it's the other. As you yourself have stated, any other netagive value other than EOF is undefiend. So why are you trying to force it? Also, your implementation has char as signed. So where does it say that -10 has to map to a printable character?

    [edit]
    As Salem pointed out earlier, you are relying on your implementation having char as signed to prove your point. Recompile with '-funsigned-char' and try again. At any rate, the following post is still true.
    [/edit]


    Quzah.
    Last edited by quzah; 06-29-2005 at 05:23 PM.
    Hope is the first step on the road to disappointment.

  11. #41
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Dave_Sinkula
    So you'd do this to avoid the cast?
    Casting EOF is incorrect. That was my point. Scroll back to the very first post I mention casting, and you'll see my reference to EOF. So, if you insist on casting, all you have to do is check for EOF. My entire point was that force casting of EOF was wrong. I've yet to be proven wrong here. You can keep trying though.


    Quzah.
    Hope is the first step on the road to disappointment.

  12. #42
    FOX
    Join Date
    May 2005
    Posts
    188
    It's simple really. When you have functions that return EOF, you need to:
    1) Check for EOF, and break if encountered.
    2) If it's not EOF, cast to unsigned char.

    When you're only dealing with byte streams already in memory (read with functions like fgets), you can safely cast to unsigned char.

    If you do not cast to unsigned char, values over 127 will most likely cause undefined behaviour if the char is not unsigned (unless you manage to match the value of EOF in the conversion). This can happen if the user inputs non-ASCII characters like Dave_Sinkula demonstrated.
    Last edited by ^xor; 06-29-2005 at 07:44 PM.

  13. #43
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >(unless you manage to match the value of EOF in the conversion).
    Which you won't ever do, since EOF is a negative value.

  14. #44
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by quzah
    So how about passing it a valid value instead of -10?
    "My program only breaks if I pass it this data?" Must be a problem with the data.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  15. #45
    FOX
    Join Date
    May 2005
    Posts
    188
    > Which you won't ever do, since EOF is a negative value.

    Store a character with the value 255 in a signed char and see what happens... On my system, unqualified chars are signed by default unless I change the behaviour with a compiler switch.
    Last edited by ^xor; 06-29-2005 at 08:39 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. type safe issue
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 02-12-2008, 09:32 PM
  2. Bjarne's exception safe sample
    By George2 in forum C++ Programming
    Replies: 13
    Last Post: 12-28-2007, 05:38 PM
  3. A Safe Dialect of C
    By viaxd in forum Tech Board
    Replies: 11
    Last Post: 11-26-2003, 11:14 AM
  4. How safe is it?
    By hermit in forum A Brief History of Cprogramming.com
    Replies: 40
    Last Post: 05-08-2002, 09:33 PM
  5. Safe Mode on FreeBsd
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 10-25-2001, 09:37 AM