Discussion:
how to make it work
(too old to reply)
fir
2024-08-29 12:25:23 UTC
Permalink
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)

?
Ben Bacarisse
2024-08-29 13:04:28 UTC
Permalink
Post by fir
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.
fir
2024-08-29 13:13:58 UTC
Permalink
Post by Ben Bacarisse
Post by fir
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
#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
Ben Bacarisse
2024-08-29 15:09:19 UTC
Permalink
Post by fir
Post by Ben Bacarisse
Post by fir
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
#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.
Post by fir
- 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.
Post by fir
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.
fir
2024-08-29 16:14:02 UTC
Permalink
Post by Ben Bacarisse
Post by fir
Post by Ben Bacarisse
Post by fir
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
#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.
Post by fir
- 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.
Post by fir
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?
James Kuyper
2024-08-29 18:16:14 UTC
Permalink
fir <***@grunge.pl> writes:
...
Post by fir
Post by fir
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");
...
Post by fir
- 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'.
Post by fir
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.
fir
2024-08-29 18:24:57 UTC
Permalink
Post by James Kuyper
...
Post by fir
Post by fir
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");
...
Post by fir
- 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'.
Post by fir
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
Kaz Kylheku
2024-08-29 15:22:31 UTC
Permalink
Post by fir
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')
Post by fir
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: @***@mstdn.ca
fir
2024-08-29 16:24:32 UTC
Permalink
Post by Kaz Kylheku
Post by fir
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')
Post by fir
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
#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
Bonita Montero
2024-08-29 15:54:01 UTC
Permalink
 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.
fir
2024-08-29 16:12:02 UTC
Permalink
Post by Bonita Montero
Post by 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
Bonita Montero
2024-08-31 18:38:39 UTC
Permalink
Post by fir
my compiler seem to cut of all that to last 4
I think it isn't standardized because there's no general rule
whether the chars are beginning from the lowest or highest byte.

Loading...