Thread: Splint

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    32

    Splint

    What's your opinion on Splint and the likes? Should you use it, and how far should you go?

    My current program passes splint -weak with just a few adjustments, most of them including type casts. I'm under the impression that explicit type casts is something to avoid, and am therefore wondering about the usage and relevance of this type of tools.

    I'm compiling with -ansi -pedantic -Wall -W, by the way.

    Thanks!
    -tretton

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I've never used splint before, but I can say you won't get far in C if you keep avoiding explicit type casts. In anything but the most basic of programs, type casts become absolutely necessary.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    277
    Quote Originally Posted by tretton
    What's your opinion on Splint and the likes? Should you use it, and how far should you go?

    My current program passes splint -weak with just a few adjustments, most of them including type casts. I'm under the impression that explicit type casts is something to avoid, and am therefore wondering about the usage and relevance of this type of tools.

    I'm compiling with -ansi -pedantic -Wall -W, by the way.

    Thanks!
    -tretton
    As our mate pointed casts are a part of C, but Splint can be a nice tool to find some nifty errors. It is a nice try when your program compiles but something wierd is scaping to your sight and generating problems.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by bithub
    I've never used splint before, but I can say you won't get far in C if you keep avoiding explicit type casts. In anything but the most basic of programs, type casts become absolutely necessary.
    I'd say that over 90% of the time such explicit casts are either unnecessary or used incorrectly in C. That is what makes them dangerous. Where is it that you find such tremendous use of such conversions?
    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.*

  5. #5
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Where is it that you find such tremendous use of such conversions?
    Window procedure parameters.
    Any Windows API function which uses a long to hold parameter values (there's a ton).
    Getting DLL exported functions.
    socket functions.
    Any mathematical expression which requires a floating point value to be assigned to an integer.

    That's just scratching the surface.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by bithub
    Window procedure parameters.
    Any Windows API function which uses a long to hold parameter values (there's a ton).
    Getting DLL exported functions.
    socket functions.
    Any mathematical expression which requires a floating point value to be assigned to an integer.
    M'kay. The most likely incorrect usages.
    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. #7
    Sr. Software Engineer filker0's Avatar
    Join Date
    Sep 2005
    Location
    West Virginia
    Posts
    235
    Quote Originally Posted by Dave_Sinkula
    I'd say that over 90% of the time such explicit casts are either unnecessary or used incorrectly in C. That is what makes them dangerous. Where is it that you find such tremendous use of such conversions?
    In my current job, the C programming standard requires the use of casts when a type promotion/conversion is taking place, even if it's not an unsafe one. The standard was developed by ADA programmers. You'd be amazed at the number of casts that show up in the code... Casts between unsigned char and unsigned int, void * and anything, you name it. At one code review that I attended, I saw the following construct:
    Code:
    struct somestruct *blah = (struct somestruct *)NULL;
    and everywhere in that code module that a comparison against NULL was done, a cast to the pointer type was made. This was lauded by the SQA auditor as being how it should be done all the time.
    Insert obnoxious but pithy remark here

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by filker0
    This was lauded by the SQA auditor as being how it should be done all the time.
    Yikes! Turn off error checking so everything's kosher!
    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. #9
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    M'kay. The most likely incorrect usages.
    Wow, do I need to go down the list one by one, and show how each one of these requires a cast? Maybe then, you can show me how in each instance I am doing it incorrectly?

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by bithub
    Wow, do I need to go down the list one by one, and show how each one of these requires a cast? Maybe then, you can show me how in each instance I am doing it incorrectly?
    Sure.
    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.*

  11. #11
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Ok, I'll try to make the examples as specific as possible.

    - Window procedure parameters.
    Window messages come in the form of (HWND,UINT,WPARAM,LPARAM).
    Take the WM_CREATE message:
    The LPARAM parameter points to a CREATESTRUCT structure. In order to access that structure, a cast is necessary.
    Code:
    CREATESTRUCT *cs = (LPCREATESTRUCT)lParam;

    - Any Windows API function which uses a long to hold parameter values (there's a ton).
    Code:
    struct mystrdata *mydata = (struct mystrdata*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    or
    Code:
    struct mystrdata* mydata = (struct mystrdata*)SendMessage(hwndList, LB_GETITEMDATA,index,0);
    - Getting DLL exported functions.
    Code:
    typedef void (*somefn)(int);
    somefn myfunction = (somefn)GetProcAddress(hMod,"somefn");
    - socket functions.
    Code:
    struct sockaddr_in addr;
    /* Fill addr with bind information */
    bind(s,(struct sockaddr*)&addr,sizeof(addr));
    or
    Code:
    struct binarystruct *data = malloc(sizeof(*data));
    /* Fill data with useful information */
    send(socket,(char*)data,sizeof(data),0);

    - Any mathematical expression which requires a floating point value to be assigned to an integer.
    Code:
    float numberOfHours = 2.5f;
    int numberOfMinutes = numberOfHours * 60;

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Window procedure parameters.
    So basically, you mapped a crappy API into a general rule of always casting?

    Sure, for an API originally designed by ASM programmers (hey, an unsigned long can represent everything, we'll use that). Hell, half the API would at least benefit in using void* occasionally, for C programmers at least. C++ programmers are permanently hosed in trying to use an API defined in another era.

  13. #13
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    So basically, you mapped a crappy API into a general rule of always casting?
    What? You need to re-read my entire post instead of just the first 3 sentences. I posted instances where type casting is necessary. How you interpreted that as "a general rule of always casting" is beyond me. My rule is that I cast when I have to. Anyone else who writes programs that compile will follow the same rule.

    Hell, half the API would at least benefit in using void* occasionally
    True, but that doesn't change the fact that the APIs don't use void*, and we have to live with that.

  14. #14
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    ITHK T INTW ODHTHAPCJONTDA
    YU

    B

    *cough*If it takes a man two days to walk a fortnight, why does technology wait for no man?*cough*

    ^ KEY? ^? MAKE NO SENSE?

    Boredom is a .........., don't you agree, gentle reader?
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by bithub
    - Window procedure parameters.
    Window messages come in the form of (HWND,UINT,WPARAM,LPARAM).
    Take the WM_CREATE message:
    The LPARAM parameter points to a CREATESTRUCT structure. In order to access that structure, a cast is necessary.
    Code:
    CREATESTRUCT *cs = (LPCREATESTRUCT)lParam;
    - Any Windows API function which uses a long to hold parameter values (there's a ton).
    Code:
    struct mystrdata *mydata = (struct mystrdata*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    or
    Code:
    struct mystrdata* mydata = (struct mystrdata*)SendMessage(hwndList, LB_GETITEMDATA,index,0);
    Ah, yes, Windows. Gotta give you that. Screwed up from the start by the masters, one is forced to write bad code.

    Quote Originally Posted by bithub
    - Getting DLL exported functions.
    Code:
    typedef void (*somefn)(int);
    somefn myfunction = (somefn)GetProcAddress(hMod,"somefn");
    Function pointers do often break many guidelines, but Microsoft may assist in making it too easy.

    Quote Originally Posted by bithub
    - socket functions.
    Code:
    struct sockaddr_in addr;
    /* Fill addr with bind information */
    bind(s,(struct sockaddr*)&addr,sizeof(addr));
    Well, bind does have a prototype that I'll assume has a reason. It's a convenience here, not a necessity.

    Quote Originally Posted by bithub
    Code:
    struct binarystruct *data = malloc(sizeof(*data));
    /* Fill data with useful information */
    send(socket,(char*)data,sizeof(data),0);
    And here it would depend on the quality of implementation.

    Quote Originally Posted by bithub
    - Any mathematical expression which requires a floating point value to be assigned to an integer.
    Code:
    float numberOfHours = 2.5f;
    int numberOfMinutes = numberOfHours * 60;
    A necessity, no. Silencing a diagnostic might be the goal here, but the implicit conversion works just fine.

    So that mostly leaves us the WinAPI.
    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.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. splint usage problems
    By Kempelen in forum C Programming
    Replies: 6
    Last Post: 05-05-2008, 08:56 AM
  2. Operator Precedence?
    By cpjust in forum C++ Programming
    Replies: 53
    Last Post: 05-04-2008, 06:43 PM
  3. splint
    By kermit in forum Tech Board
    Replies: 4
    Last Post: 04-10-2004, 03:12 PM