• how to make it work

    From fir@21:1/5 to All on Thu Aug 29 14:25:23 2024
    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");


    }

    int main(void)
    {
    foo('warsaw');
    foo('paris');
    foo('new york');
    foo('old york');
    foo('very old york');

    return 'bye';
    }

    and maybe guess the result (or how it should be)
    (later i may tell you)

    the problem is how to make it work i want to use that kind of
    'tags' and would like to use it assuming at least 8 characters
    work okay i mean the code above would "catch" only on proper tag and
    each one would be printed one time

    right now it dont - is thsi a way to make it work
    (maybe except the last one as i understand
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    may be treated as the same

    (i need it to work on 32 bit old mingw/gcc)

    ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to fir on Thu Aug 29 14:04:28 2024
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");


    }

    int main(void)
    {
    foo('warsaw');
    foo('paris');
    foo('new york');
    foo('old york');
    foo('very old york');

    return 'bye';
    }

    and maybe guess the result (or how it should be)
    (later i may tell you)

    the problem is how to make it work i want to use that kind of
    'tags' and would like to use it assuming at least 8 characters
    work okay i mean the code above would "catch" only on proper tag and
    each one would be printed one time

    right now it dont - is thsi a way to make it work
    (maybe except the last one as i understand
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    may be treated as the same

    (i need it to work on 32 bit old mingw/gcc)

    That's unfortunate because this can be done in a portable and relatively convenient way in modern C:

    #include <stdint.h>
    #include <stdio.h>

    typedef union {
    unsigned char bytes[sizeof (uint64_t)];
    uint64_t tag;
    } Tag;

    void foo(Tag t)
    {
    if (t.tag == (Tag){"warsaw"}.tag)
    printf("warsaw\n");
    }

    int main(void)
    {
    foo((Tag){"warsaw"});
    }

    With a little bit more work, you can get this to work in older C without compound literals.

    But depending on what your ultimate goal is, you might want to look at
    how Lisp implementations "intern" their symbols. That can avoid the
    obvious length limitations while making for very efficient equality comparisons.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fir@21:1/5 to Ben Bacarisse on Thu Aug 29 15:13:58 2024
    Ben Bacarisse wrote:
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");


    }

    int main(void)
    {
    foo('warsaw');
    foo('paris');
    foo('new york');
    foo('old york');
    foo('very old york');

    return 'bye';
    }

    and maybe guess the result (or how it should be)
    (later i may tell you)

    the problem is how to make it work i want to use that kind of
    'tags' and would like to use it assuming at least 8 characters
    work okay i mean the code above would "catch" only on proper tag and
    each one would be printed one time

    right now it dont - is thsi a way to make it work
    (maybe except the last one as i understand
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    may be treated as the same

    (i need it to work on 32 bit old mingw/gcc)

    That's unfortunate because this can be done in a portable and relatively convenient way in modern C:

    #include <stdint.h>
    #include <stdio.h>

    typedef union {
    unsigned char bytes[sizeof (uint64_t)];
    uint64_t tag;
    } Tag;

    void foo(Tag t)
    {
    if (t.tag == (Tag){"warsaw"}.tag)
    printf("warsaw\n");
    }

    int main(void)
    {
    foo((Tag){"warsaw"});
    }

    With a little bit more work, you can get this to work in older C without compound literals.

    But depending on what your ultimate goal is, you might want to look at
    how Lisp implementations "intern" their symbols. That can avoid the
    obvious length limitations while making for very efficient equality comparisons.

    i want it in classic c - my example work on up to 4 lellets/digits/signs
    but i dont know how to make it work for 8

    as even old c has 64 bit unsigned i guess it should work, but dont know
    how to make it work

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to fir on Thu Aug 29 16:09:19 2024
    fir <fir@grunge.pl> writes:

    Ben Bacarisse wrote:
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");


    }

    int main(void)
    {
    foo('warsaw');
    foo('paris');
    foo('new york');
    foo('old york');
    foo('very old york');

    return 'bye';
    }

    and maybe guess the result (or how it should be)
    (later i may tell you)

    the problem is how to make it work i want to use that kind of
    'tags' and would like to use it assuming at least 8 characters
    work okay i mean the code above would "catch" only on proper tag and
    each one would be printed one time

    right now it dont - is thsi a way to make it work
    (maybe except the last one as i understand
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    may be treated as the same

    (i need it to work on 32 bit old mingw/gcc)

    That's unfortunate because this can be done in a portable and relatively
    convenient way in modern C:

    #include <stdint.h>
    #include <stdio.h>

    typedef union {
    unsigned char bytes[sizeof (uint64_t)];
    uint64_t tag;
    } Tag;

    void foo(Tag t)
    {
    if (t.tag == (Tag){"warsaw"}.tag)
    printf("warsaw\n");
    }

    int main(void)
    {
    foo((Tag){"warsaw"});
    }

    With a little bit more work, you can get this to work in older C without
    compound literals.

    But depending on what your ultimate goal is, you might want to look at
    how Lisp implementations "intern" their symbols. That can avoid the
    obvious length limitations while making for very efficient equality
    comparisons.

    i want it in classic c

    Why? Compound literals are a quarter of a century old.

    - my example work on up to 4 lellets/digits/signs
    but i dont know how to make it work for 8

    "Classic" C's character constants are of type int and classic C's ints
    are 16 or 32 bits wide. There is no getting round that.

    A macro like this (with your own choice of old type in the casts)

    #define TAG(s) ((uint64_t)(s[0]) | \
    (uint64_t)(s"\0"[1]) << 8 | \
    (uint64_t)(s"\0\0"[2]) << 16 | \
    (uint64_t)(s"\0\0\0"[3]) << 24 | \
    (uint64_t)(s"\0\0\0\0"[4]) << 32 | \
    (uint64_t)(s"\0\0\0\0\0"[5]) << 40 | \
    (uint64_t)(s"\0\0\0\0\0\0"[6]) << 48 | \
    (uint64_t)(s"\0\0\0\0\0\0\0"[7]) << 56)

    might just about do, but you can't get 64-bit integers using '...'
    character constants.

    as even old c has 64 bit unsigned i guess it should work, but dont know how to make it work

    Some (but not all) old C compilers support 64 bit integer types, but
    '...' constants are always of type int.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to fir on Thu Aug 29 15:22:31 2024
    On 2024-08-29, fir <fir@grunge.pl> wrote:
    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");

    #define EIGHTCC(A, B, C, D, E, F, G, H) \
    ((uint64_t) (A) << 56 | \
    (uint64_t) (B) << 48 | \
    (uint64_t) (C) << 40 | \
    (uint64_t) (D) << 32 | \
    (uint64_t) (E) << 24 | \
    (uint64_t) (F) << 16 | \
    (uint64_t) (G) << 8 | \
    (uint64_t) (H))

    #define WARSAW EIGHTCC(' ', 'w', 'a', 'r', 's', 'a', 'w')
    #define PARIS EIGHTCC(' ', ' ', 'p', 'a', 'r', 'i', 's')

    if(tag=='very old york') printf("\nvery old york");

    This one won't fit; it has 13 characters. The EIGHTCC macro
    requires exactly eight arguments, so you won't define anything
    like this by accident.

    The binary code coul use an abbreviation, while the constant
    symbol has a longer name:

    #define VERY_OLD_YORK EIGHTCC('v', 'o', 'l', 'd', 'y', 'r', 'k')

    If you care about easily reading these strings in memory dumps, you can
    adjust the calculation in EIGHTCC according to the endianness of the
    machine.

    I have it the wrong way around for the predominant little endian;
    we want to go from H to A.


    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fir@21:1/5 to Bonita Montero on Thu Aug 29 18:12:02 2024
    Bonita Montero wrote:
    Am 29.08.2024 um 14:25 schrieb fir:

    if(tag=='very old york') printf("\nvery old york");

    Isn't standard and I don't know what your compiler does with this
    since the string is beyond eight bytes. Maybe it makes a unsigned
    __int128 from that.


    my compiler seem to cut of all that to last 4

    the result of this program is


    warsaw
    paris
    new york
    old york
    very old york
    new york
    old york
    very old york
    new york
    old york
    very old york

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fir@21:1/5 to Ben Bacarisse on Thu Aug 29 18:14:02 2024
    Ben Bacarisse wrote:
    fir <fir@grunge.pl> writes:

    Ben Bacarisse wrote:
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");


    }

    int main(void)
    {
    foo('warsaw');
    foo('paris');
    foo('new york');
    foo('old york');
    foo('very old york');

    return 'bye';
    }

    and maybe guess the result (or how it should be)
    (later i may tell you)

    the problem is how to make it work i want to use that kind of
    'tags' and would like to use it assuming at least 8 characters
    work okay i mean the code above would "catch" only on proper tag and
    each one would be printed one time

    right now it dont - is thsi a way to make it work
    (maybe except the last one as i understand
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    may be treated as the same

    (i need it to work on 32 bit old mingw/gcc)

    That's unfortunate because this can be done in a portable and relatively >>> convenient way in modern C:

    #include <stdint.h>
    #include <stdio.h>

    typedef union {
    unsigned char bytes[sizeof (uint64_t)];
    uint64_t tag;
    } Tag;

    void foo(Tag t)
    {
    if (t.tag == (Tag){"warsaw"}.tag)
    printf("warsaw\n");
    }

    int main(void)
    {
    foo((Tag){"warsaw"});
    }

    With a little bit more work, you can get this to work in older C without >>> compound literals.

    But depending on what your ultimate goal is, you might want to look at
    how Lisp implementations "intern" their symbols. That can avoid the
    obvious length limitations while making for very efficient equality
    comparisons.

    i want it in classic c

    Why? Compound literals are a quarter of a century old.

    - my example work on up to 4 lellets/digits/signs
    but i dont know how to make it work for 8

    "Classic" C's character constants are of type int and classic C's ints
    are 16 or 32 bits wide. There is no getting round that.

    A macro like this (with your own choice of old type in the casts)

    #define TAG(s) ((uint64_t)(s[0]) | \
    (uint64_t)(s"\0"[1]) << 8 | \
    (uint64_t)(s"\0\0"[2]) << 16 | \
    (uint64_t)(s"\0\0\0"[3]) << 24 | \
    (uint64_t)(s"\0\0\0\0"[4]) << 32 | \
    (uint64_t)(s"\0\0\0\0\0"[5]) << 40 | \
    (uint64_t)(s"\0\0\0\0\0\0"[6]) << 48 | \
    (uint64_t)(s"\0\0\0\0\0\0\0"[7]) << 56)

    might just about do, but you can't get 64-bit integers using '...'
    character constants.

    as even old c has 64 bit unsigned i guess it should work, but dont know how >> to make it work

    Some (but not all) old C compilers support 64 bit integer types, but
    '...' constants are always of type int.


    bad news sorta hard to belive (as it could work in 64 bit version imo

    - is this for sure not working? maybe some gcc extension at least?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fir@21:1/5 to Kaz Kylheku on Thu Aug 29 18:24:32 2024
    Kaz Kylheku wrote:
    On 2024-08-29, fir <fir@grunge.pl> wrote:
    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");

    #define EIGHTCC(A, B, C, D, E, F, G, H) \
    ((uint64_t) (A) << 56 | \
    (uint64_t) (B) << 48 | \
    (uint64_t) (C) << 40 | \
    (uint64_t) (D) << 32 | \
    (uint64_t) (E) << 24 | \
    (uint64_t) (F) << 16 | \
    (uint64_t) (G) << 8 | \
    (uint64_t) (H))

    #define WARSAW EIGHTCC(' ', 'w', 'a', 'r', 's', 'a', 'w')
    #define PARIS EIGHTCC(' ', ' ', 'p', 'a', 'r', 'i', 's')

    if(tag=='very old york') printf("\nvery old york");

    This one won't fit; it has 13 characters. The EIGHTCC macro
    requires exactly eight arguments, so you won't define anything
    like this by accident.

    The binary code coul use an abbreviation, while the constant
    symbol has a longer name:

    #define VERY_OLD_YORK EIGHTCC('v', 'o', 'l', 'd', 'y', 'r', 'k')

    If you care about easily reading these strings in memory dumps, you can adjust the calculation in EIGHTCC according to the endianness of the
    machine.

    I have it the wrong way around for the predominant little endian;
    we want to go from H to A.


    this is bad i need it strictly for simplicity and convenience
    as the goal is to get rid enums which are shit becouse it spread code
    and makes terrible code jumping - makin real pain in the head if you
    write bigger program with an increasing dose of enums

    in fact instead of macro (i dont use macros) i could
    just write a normal function which takes string up to 8
    asci and generates unsigned64 from it then

    sorta lieke

    u64 convert(char^ tag)
    {
    u64 value = (u64)tag[0] + (u64)tag[1]*256 + (u64)tag[2]*256*256 + (u64)tag[3]*256*256*256 + (u64)tag[4]*256*256*256*256 + ....

    returbn value;
    }


    and as it will be passed with constant char* = "new york" ;
    i could hope that in compile time those calls would be just
    optimised to 65 bit values on assembly level

    but will it do?

    enums are overally shit and they are almost unusable and some
    alternative needs to be used

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to fir on Thu Aug 29 14:16:14 2024
    fir <fir@grunge.pl> writes:
    ...
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    ...
    - my example work on up to 4 lellets/digits/signs
    but i dont know how to make it work for 8

    "An integer character constant has type int. ... The
    value of an integer character constant containing more than one
    character, ... is implementation-defined."

    The implementation you're using apparently defines a different value for
    each possible combination of 4 characters, which is the maximum number
    allowed if sizeof(int)==4. Keep in mind that, since the mapping is implementation-defined, such code is non-portable. For instance, it's
    entirely possible that an implementation sets the value of a
    multi-character constant solely by looking at it's first or last
    characters. On some implementation, you might have 'new york' == 'k' and
    'old york' == 'k'.

    as even old c has 64 bit unsigned i guess it should work, but dont know how to make it work

    So, by "old c" you mean C99? Before C99, no integer type was guaranteed
    to have more than 32 bits.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fir@21:1/5 to James Kuyper on Thu Aug 29 20:24:57 2024
    James Kuyper wrote:
    fir <fir@grunge.pl> writes:
    ...
    fir <fir@grunge.pl> writes:

    see such code


    long long unsigned tag ;

    void foo(long long unsigned tag)
    {
    if(tag=='warsaw') printf("\nwarsaw");
    if(tag=='paris') printf("\nparis");
    if(tag=='new york') printf("\nnew york");
    if(tag=='old york') printf("\nold york");
    if(tag=='very old york') printf("\nvery old york");
    ...
    - my example work on up to 4 lellets/digits/signs
    but i dont know how to make it work for 8

    "An integer character constant has type int. ... The
    value of an integer character constant containing more than one
    character, ... is implementation-defined."

    The implementation you're using apparently defines a different value for
    each possible combination of 4 characters, which is the maximum number allowed if sizeof(int)==4. Keep in mind that, since the mapping is implementation-defined, such code is non-portable. For instance, it's entirely possible that an implementation sets the value of a
    multi-character constant solely by looking at it's first or last
    characters. On some implementation, you might have 'new york' == 'k' and
    'old york' == 'k'.

    as even old c has 64 bit unsigned i guess it should work, but dont know how >> to make it work

    So, by "old c" you mean C99? Before C99, no integer type was guaranteed
    to have more than 32 bits.

    very bad but at least clear

    hovever as c standard rules/statements or how to call it are
    dome to make c have sense then this rule should be changed
    to this

    An integer character constant mau have any integer type from simple types avalieble (it is char, short, int long etc) - the value for it is like
    adequate string ofd such walue would have in ram say 'lalalala" would heve walule of 0x6c616c616c616c61

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)