Re: Loops (was Re: do { quit; } else { })

Liste des GroupesRevenir à cl c 
Sujet : Re: Loops (was Re: do { quit; } else { })
De : bc (at) *nospam* freeuk.com (bart)
Groupes : comp.lang.c
Date : 22. Apr 2025, 00:33:48
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vu6kkt$392e6$1@dont-email.me>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
User-Agent : Mozilla Thunderbird
On 21/04/2025 21:25, Kaz Kylheku wrote:
On 2025-04-21, bart <bc@freeuk.com> wrote:
On 21/04/2025 19:43, Kaz Kylheku wrote:
On 2025-04-21, bart <bc@freeuk.com> wrote:
On 21/04/2025 04:16, Kaz Kylheku wrote:
- Because they are not gathered in one place, not only is it less>
readable, but we cannot use while write a macro such as:
>
        for_sqlite_hash (p, &pSchema->trigHash) {
          if (some_condition_over(p))
            continue; // doesn't stupidly repeat for the same p!
        }
>
I can't write such macros at all. I'm not even sure what this does.
>
Have you never worked with a large codebase written by someone other
than you?
>
How large are we talking about?
 Several 100K to millions.
Characters, lines or files of source code, or bytes of binary?

 
I've delved into largish apps in the context of getting my C compiler
working. I would describe that experience as 'brutal'.
 Well, that brutal experience is the job of the career software engineer,
believe it or not. Very few work only on their own original code.
 
If you need to
debug someone else's codebase, not to find bugs in that program, but to
find why your implementation is failing, then you want as conservative a
coding style as possible.
>
>
When you open a random file in an unfamiliar code base, pretty
much any function call that is not in the standard library triggers
the "I don't know what this does" response.
>
Yes, a function call. Macros are in an entirely different, evil category.
 No, they aren't. They are just another definition to understand.
I've seen a 33KB C file that expanded to 4MB after preprocessing. Macros are evil.

 They can be misused, and also used to make solutions that are more
complicated than some great ideas that don't involve macros.
You can tell when there is abuse going on, because you find that instead of optimising doubling the speed of a program, it will make it 3-4 times as fast. Because layers of macros hide the fact that that there are also multiple layers of functions which need serious inlining.

So can anything: an open coded function can be misused to make some
complicated solution that can be more nicely done with macros.

The Lua sources (only a mere 30Kloc), use macros extensively, but also
have a habit of giving them ordinary looking names in lower case so that
they look like function calls.
 So does ISO C; e.g. assert (expr); offsetof (type, member). So what?

Macros that provide syntax should blend into the language.
These didn't provide syntax.
Here's a nice example:
         op_arith(L, l_addi, luai_numadd);
Innocent-looking isn't it? It expands to this:
  {TValue*v1=(&((base+((((int)((((i)>>((((0+7)+8)+1)))&((~((~(Instruction)0)<<(8)))<<(0)))))))))->val);TValue*v2=(&((base+((((int)((((i)>>(((((0+7)+8)+1)+8)))&((~((~(Instruction)0)<<(8)))<<(0)))))))))->val);{StkId ra=(base+(((int)((((i)>>((0+7)))&((~((~(Instruction)0)<<(8)))<<(0)))))));if(((((v1))->tt_)==(((3)|((0)<<4))))&&((((v2))->tt_)==(((3)|((0)<<4))))){lua_Integer i1=(((v1)->value_).i);lua_Integer i2=(((v2)->value_).i);pc++;{TValue*io=((&(ra)->val));((io)->value_).i=(((lua_Integer)(((lua_Unsigned)(i1))+((lua_Unsigned)(i2)))));((io)->tt_=(((3)|((0)<<4))));};}else{lua_Number n1;lua_Number n2;if((((((v1))->tt_)==(((3)|((1)<<4))))?((n1)=(((v1)->value_).n),1):(((((v1))->tt_)==(((3)|((0)<<4))))?((n1)=((lua_Number)(((((v1)->value_).i)))),1):0))&&(((((v2))->tt_)==(((3)|((1)<<4))))?((n2)=(((v2)->value_).n),1):(((((v2))->tt_)==(((3)|((0)<<4))))?((n2)=((lua_Number)(((((v2)->value_).i)))),1):0))){pc++;{TValue*io=((&(ra)->val));((io)->value_).n=(((n1)+(n2)));((io)->tt_=(((3)|((1)<<4))));};}};};};
 From this, I had to find the bug in my compiler.
(Lua is an interpreter; I write interpreters and they are several times faster than Lua for equivalant inputs. I don't need to use such tricks.)

Please humour me: What Does It Do?
 It is intended to condense an interation that *you* open-coded, in this
example upthread:
         p = sqliteHashFirst(&pSchema->trigHash);
        while (p != NULL)
        {
            sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
            p = sqliteHashNext(p) )
        }
 So although I didn't show the definition, I think, of course the intent that it
does this (i.e. is relevant to the discussion thread) and not something else.
    for_sqlite_hash (p, hashptr) stmet
 must initialize p using sqliteHashFirst(hashPtr);
This sounds a very specific type of macro, just to replace a simple loop. And it is simple; those identifiers make it look scary. This is the loop:
      p = a;
      while (p) {
          stmt;
          p = next();            // which turns out to be p = p->next
      }
Given that, do you /really/ need that extra layer of complexity via that macro?

If I had to write 17 loops over SQLite hashes, I'd rather type
for_sqlite_hash(p, hash)  than
for (p = sqliteHashFirst(hash); p; p = sqliteHashNext(hash)).
I guess that answers that question! I'd use macros only as a last resort; you would use them at the first opportunity.

Date Sujet#  Auteur
23 Apr 26 o 

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal