A generic interface for numeric variables

Discussion in 'C Programming' started by pozz, Apr 4, 2011.

  1. pozz

    pozz Guest

    In C I can have a small set of numeric type variables: char, short,
    int and long (ignoring long long), and their unsigned counterpart.
    In one of my program, I have a lot of (about 200) numeric variables of
    different types, signed and unsigned.

    Now I want to create a generic function that shows the value of a
    variable on the display with a format string dependent on the
    variable, increase/decrease it inside a range dependent on the
    variable and set it the new value.

    I create the following code... do you have any suggestions or
    improvements? It seems to me too complex to read (a lot of if(p-
    >type)... )


    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>

    signed char sc = -1;
    unsigned char uc = UCHAR_MAX;
    signed short ss = -1;
    unsigned short us = SHRT_MAX;
    signed int si = -1;
    unsigned int ui = UINT_MAX;
    signed long int sl = -1;
    unsigned long int ul = ULONG_MAX;

    typedef struct {
    enum {
    NUM_TYPE_SCHAR,
    NUM_TYPE_UCHAR,
    NUM_TYPE_SSHRT,
    NUM_TYPE_USHRT,
    NUM_TYPE_SINT,
    NUM_TYPE_UINT,
    NUM_TYPE_SLONG,
    NUM_TYPE_ULONG,
    } type;
    void *ptr;
    const char *fmt;
    union {
    signed char min_sc;
    unsigned char min_uc;
    signed short min_ss;
    unsigned short min_us;
    signed int min_si;
    unsigned int min_ui;
    signed long min_sl;
    unsigned long min_ul;
    } min;
    union {
    signed char max_sc;
    unsigned char max_uc;
    signed short max_ss;
    unsigned short max_us;
    signed int max_si;
    unsigned int max_ui;
    signed long max_sl;
    unsigned long max_ul;
    } max;
    } num_t;

    /* Just some example variables */
    num_t num_sc = { NUM_TYPE_SCHAR, &sc, "%d degrees", { .min_sc = -10 },
    { .max_sc = 10 } };
    num_t num_uc = { NUM_TYPE_UCHAR, &uc, "%u apples", { .min_sc = 0 },
    { .max_sc = UCHAR_MAX } };
    num_t num_ss = { NUM_TYPE_SSHRT, &ss, "%d points", { .min_ss = -10 },
    { .max_ss = 10 } };
    num_t num_us = { NUM_TYPE_USHRT, &us, "%u meters", { .min_ss = 0 },
    { .max_ss = USHRT_MAX } };
    num_t num_si = { NUM_TYPE_SINT, &si, "%d dollars", { .min_si = -10 },
    { .max_si = 10 } };
    num_t num_ui = { NUM_TYPE_UINT, &ui, "%u seconds", { .min_si = 0 },
    { .max_si = UINT_MAX } };
    num_t num_sl = { NUM_TYPE_SLONG, &sl, "%d depth", { .min_sl = -10 },
    { .max_sl = 10 } };
    num_t num_ul = { NUM_TYPE_ULONG, &ul, "%u km", { .min_sl = 0 },
    { .max_sl = ULONG_MAX } };

    void
    num_print(num_t *num)
    {
    if (num->type == NUM_TYPE_SCHAR) {
    printf (num->fmt, *(signed char *)num->ptr);
    } else if (num->type == NUM_TYPE_UCHAR) {
    printf (num->fmt, *(unsigned char *)num->ptr);
    } else if (num->type == NUM_TYPE_SSHRT) {
    printf (num->fmt, *(signed short *)num->ptr);
    } else if (num->type == NUM_TYPE_USHRT) {
    printf (num->fmt, *(unsigned short *)num->ptr);
    }
    /* ... */
    }
    void
    num_increase(num_t *num)
    {
    if (num->type == NUM_TYPE_SCHAR) {
    signed char value = *(signed char *)num->ptr;
    if (value < num->max.max_sc) {
    *(signed char *)(num->ptr) = ++value;
    }
    } else if (num->type == NUM_TYPE_UCHAR) {
    unsigned char value = *(unsigned char *)num->ptr;
    if (value < num->max.max_uc) {
    *(unsigned char *)(num->ptr) = ++value;
    }
    } else if (num->type == NUM_TYPE_SSHRT) {
    signed short value = *(signed short *)num->ptr;
    if (value < num->max.max_ss) {
    *(signed short *)(num->ptr) = ++value;
    }
    } else if (num->type == NUM_TYPE_USHRT) {
    unsigned short value = *(unsigned short *)num->ptr;
    if (value < num->max.max_us) {
    *(unsigned short *)(num->ptr) = ++value;
    }
    }
    /* ... */
    }

    void
    num_decrease(num_t *num)
    {
    if (num->type == NUM_TYPE_SCHAR) {
    signed char value = *(signed char *)num->ptr;
    if (value > num->min.min_sc) {
    *(signed char *)(num->ptr) = --value;
    }
    } else if (num->type == NUM_TYPE_UCHAR) {
    unsigned char value = *(unsigned char *)num->ptr;
    if (value > num->min.min_uc) {
    *(unsigned char *)(num->ptr) = --value;
    }
    } else if (num->type == NUM_TYPE_SSHRT) {
    signed short value = *(signed short *)num->ptr;
    if (value > num->min.min_ss) {
    *(signed short *)(num->ptr) = --value;
    }
    } else if (num->type == NUM_TYPE_USHRT) {
    unsigned short value = *(unsigned short *)num->ptr;
    if (value > num->min.min_us) {
    *(unsigned short *)(num->ptr) = --value;
    }
    }
    /* ... */
    }

    void
    num_cpyvalue(num_t *dst, const num_t *src)
    {
    if (dst->type == NUM_TYPE_SCHAR) {
    *(signed char *)dst->ptr = *(signed char *)src->ptr;
    } else if (dst->type == NUM_TYPE_UCHAR) {
    *(unsigned char *)dst->ptr = *(unsigned char *)src->ptr;
    } else if (dst->type == NUM_TYPE_SSHRT) {
    *(signed short *)dst->ptr = *(signed short *)src->ptr;
    } else if (dst->type == NUM_TYPE_USHRT) {
    *(unsigned short *)dst->ptr = *(unsigned short *)src->ptr;
    }
    /* ... */
    }

    void
    num_change(num_t *num)
    {
    char c;
    num_t num_new = *num;
    signed char new_sc;
    unsigned char new_uc;
    signed short new_ss;
    unsigned short new_us;
    /* ... */

    if (num->type == NUM_TYPE_SCHAR) {
    new_sc = *(signed char *)num->ptr;
    num_new.ptr = &new_sc;
    } else if (num->type == NUM_TYPE_UCHAR) {
    new_uc = *(unsigned char *)num->ptr;
    num_new.ptr = &new_uc;
    } else if (num->type == NUM_TYPE_SSHRT) {
    new_ss = *(signed short *)num->ptr;
    num_new.ptr = &new_ss;
    } else if (num->type == NUM_TYPE_USHRT) {
    new_us = *(unsigned short *)num->ptr;
    num_new.ptr = &new_us;
    }

    printf("The value is: ");
    num_print(num);
    putchar('\n');

    printf ("Press U/D/O: ");
    do {
    c = getchar();
    if (c == '\n') {
    continue;
    } else if ((c == 'U') || (c == 'u')) {
    num_increase (&num_new);
    } else if ((c == 'D') || (c == 'd')) {
    num_decrease (&num_new);
    } else if ((c == 'O') || (c == 'o')) {
    break;
    }
    printf("The value is: ");
    num_print(&num_new);
    putchar('\n');
    printf ("Press U/D/O: ");
    } while ((c != 'O') && (c != 'o'));
    num_cpyvalue (num, &num_new);
    }

    int
    main (int argc, char *argv[])
    {
    num_change (&num_sc);
    printf ("The new value is: ");
    num_print(&num_sc);
    putchar('\n');
    return 0;
    }
    pozz, Apr 4, 2011
    #1
    1. Advertising

  2. pozz

    Nobody Guest

    On Mon, 04 Apr 2011 08:39:14 -0700, pozz wrote:

    > I create the following code... do you have any suggestions or
    > improvements?


    Use C++ ;)
    Nobody, Apr 4, 2011
    #2
    1. Advertising

  3. pozz

    pozz Guest

    On 4 Apr, 21:34, Nobody <> wrote:
    > On Mon, 04 Apr 2011 08:39:14 -0700, pozz wrote:
    > > I create the following code... do you have any suggestions or
    > > improvements?

    >
    > Use C++ ;)


    Unfortunately I can't :)
    pozz, Apr 5, 2011
    #3
  4. pozz

    Eric Sosman Guest

    On 4/4/2011 11:39 AM, pozz wrote:
    > In C I can have a small set of numeric type variables: char, short,
    > int and long (ignoring long long), and their unsigned counterpart.
    > In one of my program, I have a lot of (about 200) numeric variables of
    > different types, signed and unsigned.
    >
    > Now I want to create a generic function that shows the value of a
    > variable on the display with a format string dependent on the
    > variable, increase/decrease it inside a range dependent on the
    > variable and set it the new value.
    >
    > I create the following code... do you have any suggestions or
    > improvements? It seems to me too complex to read (a lot of
    > if(p->type)... )
    > [...]


    I agree: It's too complex. Let's try to simplify, shall we?

    First, I see no need for all of `signed char', `signed short',
    `signed int', and `signed long': Just let `signed long' stand in
    for the whole batch. You're placing upper and lower bounds on
    each value anyway, so if the value's bounds are within the range
    of `signed short' they are also within the range of `signed long'.
    Thanks to the bounds you will never over- or underflow, so you
    needn't worry about `signed char' and `signed int' behaving
    differently with out-of-range results; the out-of-range results
    will never occur in the first place.

    Similar remarks apply to the `unsigned' variants. Since the
    wrap-around behavior of `unsigned' arithmetic is well-defined, there
    are circumstances where `unsigned short' and `unsigned long' will in
    fact behave differently but reliably. However, your own upper and
    lower bounds still lurk in the background: If you never try to go
    below the lower nor above the upper, you never encounter wrap-around
    situations anyhow. So if wrap-around doesn't happen, you don't rely
    on `unsigned char' and `unsigned int' having different ranges, and
    you can use `unsigned long' as a proxy for the entire suite.

    Okay, we've simplified by reducing eight possibilities to just
    two. (Somebody's sure to say we're wasting space by using a `long'
    where a `char' would suffice, but any such Somebody hasn't been
    paying attention: Your present scheme uses a `union' of all the
    candidate types, so you use a `long's worth of space even for a
    `char' variable. Using `long' for everything takes no more space
    than you're already using.)

    You could go ahead with a three-quarters-reduced version of
    your current scheme, but now that the possibilities are down to two
    (signed vs. unsigned) I'd be strongly tempted to say "Two is a
    manageable number; I'll handle the two types separately." This is
    optional, of course, but it has the advantage of eliminating all
    those `if's you find so objectionable. You'd get something like

    typedef struct {
    signed long val;
    signed long min;
    signed long max;
    } Signed;

    typedef struct {
    unsigned long val;
    unsigned long min;
    unsigned long max;
    } Unsigned;

    void increaseSigned(Signed *thing);
    ...
    void decreaseUnsigned(Unsigned *thing);
    ...

    Signed celsius = { 0, -273, LONG_MAX };
    Unsigned kelvin = { 273, 0, ULONG_MAX );
    ...

    increaseSigned(&celsius);
    decreaseUnsigned(&kelvin);

    This has the disadvantage that you must remember whether to use
    the signedXxx() or unsignedXxx() function -- but then, the compiler
    will tell you if you get it wrong. With two possibilities instead of
    eight this seems not too great a burden, but if you dislike even that
    much you can always stick a type code into the `struct', as in your
    original scheme.

    Another thing to consider is that the range limits probably aren't
    specific to each variable instance, but to whatever the variable's
    value measures. It's so-and-so many splonders in a bank account, or
    so-and-so many poods per dunam of fertilizer, or so-and-so many
    centicenturies of post-secondary education. This suggests separating
    the ranges from the values, leading to a rather different scheme:

    typedef struct {
    signed long min;
    signed long max;
    } SignedRange;

    typedef struct {
    unsigned long min;
    unsigned long max;
    } UnsignedRange;

    signed long increaseSigned(signed long value,
    const SignedRange *range);
    ...
    unsigned long decreaseUnsigned(unsigned long value,
    const UnsignedRange *range);
    ...

    const SignedRange celsiusRange = { -273, LONG_MAX };
    const UnsignedRange kelvinRange = { 0, ULONG_MAX };
    ...

    signed long celsius = 0;
    unsigned long kelvin = 273;
    ...

    celsius = increaseSigned(celsius, &celsiusRange);
    kelvin = decreaseSigned(kelvin, &kelvinRange);

    Note that this works (with suitable ranges) even if `celsius'
    is `signed short' and `kelvin' is `unsigned char': C's argument
    promotions and assignment conversions allow you to use the `long'
    functions with narrower quantities. Of course, you *can* stick
    with per-instance ranges, if that makes more sense for your problem,
    but per-"scale" ranges may turn out to be more convenient.

    Summary: Three-quarters of your complexity can be done away with
    at one stroke. You may choose to live with what remains, or to adopt
    a slightly different API.

    --
    Eric Sosman
    d
    Eric Sosman, Apr 6, 2011
    #4
  5. pozz

    pozz Guest

    On 6 Apr, 03:30, Eric Sosman <> wrote:
    > [...]
    > Okay, we've simplified by reducing eight possibilities to just
    > two. (Somebody's sure to say we're wasting space by using a `long'
    > where a `char' would suffice, but any such Somebody hasn't been
    > paying attention: Your present scheme uses a `union' of all the
    > candidate types, so you use a `long's worth of space even for a
    > `char' variable. Using `long' for everything takes no more space
    > than you're already using.)


    The approach I presented is a small variation of the one I'm really
    using.
    I need to declare const structures to save precious RAM space on
    my embedded platform, but I can't initialize whatever member of
    unions/structs (a limit of the compiler). So my real scheme doesn't
    use unions but a struct/substruct approach:

    typedef struct {
    signed char *ptr;
    signed char min;
    signed char max;
    } scnum_t;

    typedef struct {
    unsigned char *ptr;
    unsigned char min;
    unsigned char max;
    } ucnum_t;

    /*...*/

    typedef struct {
    enum {
    NUM_TYPE_SCHAR,
    NUM_TYPE_UCHAR,
    NUM_TYPE_SSHRT,
    NUM_TYPE_USHRT,
    NUM_TYPE_SINT,
    NUM_TYPE_UINT,
    NUM_TYPE_SLONG,
    NUM_TYPE_ULONG,
    } type;
    void *subnum; /* Pointer to scnum_t, ucnum_t, ... */
    } num_t;

    In this case I can write:

    signed char temp; /* The variable */
    const scnum_t snTemperature = { &temp, -10, +10 };
    const num_t nTemperature = { NUM_TYPE_SCHAR, &snTemperature };

    With an additional pointer (subnum in num_t), I can declare min/max
    values as the correct type, so without losing space declaring long or
    unsigned long min/max.
    Most of the variables have small values, so they are already declared
    as signed/unsigned char/short. In that case, on a 16-bit platform
    (like the one I'm using), I need one num_t struct (4 bytes) and one
    "subnum" struct (4 bytes).
    If subnum types are incorporated into num_t with min/max as long, I
    need only one num_t struct (12 bytes) for all variables.
    With my approach I can save 4 bytes for each "small values" variable.

    Anyway this isn't a very big problem, because I have a lot of "const"
    space in non-volatile memory.


    > You could go ahead with a three-quarters-reduced version of
    > your current scheme, but now that the possibilities are down to two
    > (signed vs. unsigned) I'd be strongly tempted to say "Two is a
    > manageable number; I'll handle the two types separately." This is
    > optional, of course, but it has the advantage of eliminating all
    > those `if's you find so objectionable. You'd get something like
    >
    > typedef struct {
    > signed long val;
    > signed long min;
    > signed long max;
    > } Signed;
    >
    > typedef struct {
    > unsigned long val;
    > unsigned long min;
    > unsigned long max;
    > } Unsigned;


    I can't do in this way. The variables are also declared and used in
    several parts of the code and in different modules I can't touch.
    So the numeric value can't reside inside Signed/Unsigned struct.
    I have to use a pointer to the variable.

    typedef struct {
    enum {
    NUM_TYPE_SCHAR,
    NUM_TYPE_SSHRT,
    NUM_TYPE_SINT,
    NUM_TYPE_SLONG
    } type;
    void *ptr; /* Pointer to signed char/short/int as in type
    */
    signed long min;
    signed long max;
    } Signed;

    typedef struct {
    enum {
    NUM_TYPE_UCHAR,
    NUM_TYPE_USHRT,
    NUM_TYPE_UINT,
    NUM_TYPE_ULONG
    } type;
    void *ptr; /* Pointer to unsigned char/short/int as in
    type */
    unsigned long min;
    unsigned long max;
    } Unsigned;

    But, in this case, the compiler can't give me warning if I wrongly
    assign to ptr member of Signed/Unsigned struct a variable with a
    different type as indicated in the type member.
    Also this can be a minor problem (in my struct/substruct approach
    above, I have the same problem with subnum that is void*).


    > [...]
    > Another thing to consider is that the range limits probably aren't
    > specific to each variable instance, but to whatever the variable's
    > value measures. It's so-and-so many splonders in a bank account, or
    > so-and-so many poods per dunam of fertilizer, or so-and-so many
    > centicenturies of post-secondary education. This suggests separating
    > the ranges from the values, leading to a rather different scheme:
    >
    > typedef struct {
    > signed long min;
    > signed long max;
    > } SignedRange;
    >
    > typedef struct {
    > unsigned long min;
    > unsigned long max;
    > } UnsignedRange;
    >
    > signed long increaseSigned(signed long value,
    > const SignedRange *range);
    > ...
    > unsigned long decreaseUnsigned(unsigned long value,
    > const UnsignedRange *range);
    > ...
    >
    > const SignedRange celsiusRange = { -273, LONG_MAX };
    > const UnsignedRange kelvinRange = { 0, ULONG_MAX };
    > ...
    >
    > signed long celsius = 0;
    > unsigned long kelvin = 273;
    > ...
    >
    > celsius = increaseSigned(celsius, &celsiusRange);
    > kelvin = decreaseSigned(kelvin, &kelvinRange);
    >
    > Note that this works (with suitable ranges) even if `celsius'
    > is `signed short' and `kelvin' is `unsigned char': C's argument
    > promotions and assignment conversions allow you to use the `long'
    > functions with narrower quantities. Of course, you *can* stick
    > with per-instance ranges, if that makes more sense for your problem,
    > but per-"scale" ranges may turn out to be more convenient.


    This sounds very good. I can continue using already defined variables
    with their "natural" type and use the automatic promotion/assignment
    conversion of C.


    > Summary: Three-quarters of your complexity can be done away with
    > at one stroke. You may choose to live with what remains, or to adopt
    > a slightly different API.


    Thank you very much for your suggestions and for spending some time
    to help me. I appreciated it.
    pozz, Apr 7, 2011
    #5
  6. pozz

    Eric Sosman Guest

    On 4/7/2011 6:32 AM, pozz wrote:
    > On 6 Apr, 03:30, Eric Sosman<> wrote:
    >> [...]
    >> Okay, we've simplified by reducing eight possibilities to just
    >> two. (Somebody's sure to say we're wasting space by using a `long'
    >> where a `char' would suffice, but any such Somebody hasn't been
    >> paying attention: Your present scheme uses a `union' of all the
    >> candidate types, so you use a `long's worth of space even for a
    >> `char' variable. Using `long' for everything takes no more space
    >> than you're already using.)

    >
    > The approach I presented is a small variation of the one I'm really
    > using.


    Oh, g-r-e-a-t! Well, then, the suggestions I offer are "small
    variations of helpful."

    > I need to declare const structures to save precious RAM space on
    > my embedded platform, but I can't initialize whatever member of
    > unions/structs (a limit of the compiler). So my real scheme doesn't
    > use unions but a struct/substruct approach:
    >
    > typedef struct {
    > signed char *ptr;
    > signed char min;
    > signed char max;
    > } scnum_t;
    >
    > typedef struct {
    > unsigned char *ptr;
    > unsigned char min;
    > unsigned char max;
    > } ucnum_t;
    >
    > /*...*/
    >
    > typedef struct {
    > enum {
    > NUM_TYPE_SCHAR,
    > NUM_TYPE_UCHAR,
    > NUM_TYPE_SSHRT,
    > NUM_TYPE_USHRT,
    > NUM_TYPE_SINT,
    > NUM_TYPE_UINT,
    > NUM_TYPE_SLONG,
    > NUM_TYPE_ULONG,
    > } type;
    > void *subnum; /* Pointer to scnum_t, ucnum_t, ... */
    > } num_t;
    >
    > In this case I can write:
    >
    > signed char temp; /* The variable */
    > const scnum_t snTemperature = {&temp, -10, +10 };
    > const num_t nTemperature = { NUM_TYPE_SCHAR,&snTemperature };


    And you do all this to "save precious RAM?" Ye gods! You plan
    to "save" RAM by replacing every variable-and-two-limits with a
    variable *and* a struct containing the limits *and* a pointer to
    the variable *and* a type code?

    > With an additional pointer (subnum in num_t), I can declare min/max
    > values as the correct type, so without losing space declaring long or
    > unsigned long min/max.


    R-i-i-i-g-h-t.

    > Most of the variables have small values, so they are already declared
    > as signed/unsigned char/short. In that case, on a 16-bit platform
    > (like the one I'm using), I need one num_t struct (4 bytes) and one
    > "subnum" struct (4 bytes).


    Plus the variable itself, for 9 bytes in all (for chars). If
    you jettisoned the damn pointers and the type code and just put the
    value and limits into one struct, you'd use 3 bytes per variable --
    maybe 4, if the compiler pads structs rather freely -- instead of
    the 9 you use in your current scheme (*if* it's truly your current
    scheme, and not yet another "small variation").

    If RAM is so "precious" that you eagerly seek ways to triple
    your usage thereof, I'd like to sell you a truly precious bridge.

    > If subnum types are incorporated into num_t with min/max as long, I
    > need only one num_t struct (12 bytes) for all variables.
    > With my approach I can save 4 bytes for each "small values" variable.


    Adding 200% overhead is a funny form of "savings."

    > Anyway this isn't a very big problem, because I have a lot of "const"
    > space in non-volatile memory.


    Please reconcile "isn't a very big problem" with "precious."
    Also, please explain why you need upper/lower range limits to bracket
    the values of const variables.

    >> You could go ahead with a three-quarters-reduced version of
    >> your current scheme, but now that the possibilities are down to two
    >> (signed vs. unsigned) I'd be strongly tempted to say "Two is a
    >> manageable number; I'll handle the two types separately." This is
    >> optional, of course, but it has the advantage of eliminating all
    >> those `if's you find so objectionable. You'd get something like
    >>
    >> typedef struct {
    >> signed long val;
    >> signed long min;
    >> signed long max;
    >> } Signed;
    >>
    >> typedef struct {
    >> unsigned long val;
    >> unsigned long min;
    >> unsigned long max;
    >> } Unsigned;

    >
    > I can't do in this way. The variables are also declared and used in
    > several parts of the code and in different modules I can't touch.
    > So the numeric value can't reside inside Signed/Unsigned struct.
    > I have to use a pointer to the variable.


    You don't know how to point at an element of a struct?

    > typedef struct {
    > enum {
    > NUM_TYPE_SCHAR,
    > NUM_TYPE_SSHRT,
    > NUM_TYPE_SINT,
    > NUM_TYPE_SLONG
    > } type;
    > void *ptr; /* Pointer to signed char/short/int as in type
    > */
    > signed long min;
    > signed long max;
    > } Signed;
    >
    > typedef struct {
    > enum {
    > NUM_TYPE_UCHAR,
    > NUM_TYPE_USHRT,
    > NUM_TYPE_UINT,
    > NUM_TYPE_ULONG
    > } type;
    > void *ptr; /* Pointer to unsigned char/short/int as in
    > type */
    > unsigned long min;
    > unsigned long max;
    > } Unsigned;
    >
    > But, in this case, the compiler can't give me warning if I wrongly
    > assign to ptr member of Signed/Unsigned struct a variable with a
    > different type as indicated in the type member.


    Under your current (?) scheme(s?), the compiler can't warn you
    about *any* mismatches. Failure to warn about *some* mismatches
    is therefore an improvement.

    > Also this can be a minor problem (in my struct/substruct approach
    > above, I have the same problem with subnum that is void*).


    Non capisco.

    >> [...]


    --
    Eric Sosman
    d
    Eric Sosman, Apr 8, 2011
    #6
  7. In article <inlpkl$cof$>,
    Eric Sosman <> ranted:
    >On 4/7/2011 6:32 AM, pozz wrote:
    >> On 6 Apr, 03:30, Eric Sosman<> wrote:
    >>> [...]
    >>> Okay, we've simplified by reducing eight possibilities to just
    >>> two. (Somebody's sure to say we're wasting space by using a `long'
    >>> where a `char' would suffice, but any such Somebody hasn't been
    >>> paying attention: Your present scheme uses a `union' of all the
    >>> candidate types, so you use a `long's worth of space even for a
    >>> `char' variable. Using `long' for everything takes no more space
    >>> than you're already using.)

    >>
    >> The approach I presented is a small variation of the one I'm really
    >> using.

    >
    > Oh, g-r-e-a-t! Well, then, the suggestions I offer are "small
    >variations of helpful."

    (etc)

    The boy has issues.

    --
    Windows 95 n. (Win-doze): A 32 bit extension to a 16 bit user interface for
    an 8 bit operating system based on a 4 bit architecture from a 2 bit company
    that can't stand 1 bit of competition.

    Modern day upgrade --> Windows XP Professional x64: Windows is now a 64 bit
    tweak of a 32 bit extension to a 16 bit user interface for an 8 bit
    operating system based on a 4 bit architecture from a 2 bit company that
    can't stand 1 bit of competition.
    Kenny McCormack, Apr 8, 2011
    #7
  8. pozz <> writes:
    > Il 08/04/2011 16:05, Kenny McCormack ha scritto:
    >> The boy has issues.

    >
    > Oh yes, I have many issues... but I think a lot of boys are in the same
    > situations. The difference is I know it, they don't.
    >
    > I'm sorry if I'm disturbing this ng with my stupid questions or
    > considerations. I'm not a C guru and I have many things to learn yet
    > about this language. If newbies can't post here, I stop immediately.


    A quick look at Kenny McCormack's posting history here should
    tell you whether there's any point in paying any attention to him.
    (Hint: there isn't.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 9, 2011
    #8
  9. In article <ino0gf$dn7$>, pozz <> wrote:
    >Il 08/04/2011 16:05, Kenny McCormack ha scritto:
    >> The boy has issues.

    >
    >Oh yes, I have many issues... but I think a lot of boys are in the same
    >situations. The difference is I know it, they don't.
    >
    >I'm sorry if I'm disturbing this ng with my stupid questions or
    >considerations. I'm not a C guru and I have many things to learn yet
    >about this language. If newbies can't post here, I stop immediately.


    The boy I was talking about was Eric

    Not you.

    Pay no attention to the troll "Kiki" Thompson.

    --
    (This discussion group is about C, ...)

    Wrong. It is only OCCASIONALLY a discussion group
    about C; mostly, like most "discussion" groups, it is
    off-topic Rorsharch [sic] revelations of the childhood
    traumas of the participants...
    Kenny McCormack, Apr 9, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Murat Tasan
    Replies:
    1
    Views:
    8,022
    Chaitanya
    Feb 3, 2009
  2. Replies:
    5
    Views:
    909
    X-Centric
    Jun 30, 2005
  3. darrel
    Replies:
    4
    Views:
    786
    darrel
    Jul 19, 2007
  4. jobs

    int to numeric numeric(18,2) ?

    jobs, Jul 21, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    932
    =?ISO-8859-1?Q?G=F6ran_Andersson?=
    Jul 22, 2007
  5. pozz
    Replies:
    8
    Views:
    261
    Keith Thompson
    Apr 11, 2011
Loading...

Share This Page