1

Mmmmmmmmmm

#define MAY(_y)                                                               \
 ({                                                                           \
 typeof (_y) _x = (_y); may_t _z =                                            \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), signed int),  \
    MAY_SLONG (*(signed long*)&_x),                                           \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), unsigned int),\
    MAY_ULONG (*(unsigned long*)&_x),                                         \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), signed long), \
    MAY_SLONG (*(signed long*)&_x),                                           \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x),unsigned long),\
    MAY_ULONG (*(unsigned long*)&_x),                                         \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpz_t),       \
    MAY_MPZ (*(mpz_t*)&_x),                                                   \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpq_t),       \
    MAY_MPQ (*(mpq_t*)&_x),                                                   \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpfr_t),      \
    MAY_MPFR (*(mpfr_t*)&_x),                                                 \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), long double), \
    MAY_LONG_DOUBLE (*(long double*)&_x),                                     \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), double),   \
    MAY_DOUBLE (*(double*)&_x),                                               \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), float),    \
    MAY_DOUBLE (*(double*)&_x),                                               \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char []),  \
    MAY_STRING (*(char**)&_x),                                                \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char *),   \
    MAY_STRING (*(char**)&_x),                                                \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), may_t),    \
    (_x),                                                                     \
   /* The void expression results in a compile-time error                     \
      when assigning the result to something.  */                             \
 (void)0)))))))))))));                                                        \
 _z; })

Non, il n'y a rien en trop. grin Meme si l'utilisation de _z n'est pas indispensable
(Je vous passe les definition des constructeurs specialises wink)

2

hehe

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

3

Ben, c'est tout à fait clair et logique. C'est très simple. Oui, sérieusement!
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

4

Version corrigee et amelioree.
J'ajoute bientot la possibilite (avec builtin_constant #powa#) de faire des constructeurs d'inialisations statiques:

#define MAY(_y)                                                               \
 ({                                                                           \
 typeof (_y) _x = (_y); may_t _z  =                                           \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), signed int),  \
    MAY_SLONG_C ((signed long) _x),                                           \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), unsigned int),\
    MAY_ULONG_C ((unsigned long) _x),                                         \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), signed long), \
    MAY_SLONG_C ((signed long) _x),                                           \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x),unsigned long),\
    MAY_ULONG_C ((unsigned long) _x),                                         \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpz_t),       \
    MAY_MPZ_C ((mpz_srcptr) (unsigned long) _x),                              \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x),__mpz_struct*),\
    MAY_MPZ_C ((mpz_srcptr) (unsigned long) _x),                              \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpq_t),       \
    MAY_MPQ_C ((mpq_srcptr) (unsigned long) _x),                              \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), mpfr_t),      \
    MAY_MPFR_C ((mpfr_srcptr) (unsigned long) _x),                            \
 __builtin_choose_expr(__builtin_types_compatible_p(typeof(_x), long double), \
    MAY_LONG_DOUBLE_C ( *((long double*) (void*) &_x)),                       \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), double),   \
    MAY_DOUBLE_C (*((double*)(void*)&_x)),                                    \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), float),    \
    MAY_DOUBLE_C (*((double*)(void*)&_x)),                                    \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char []),  \
    MAY_STRING_C ((const char*) (unsigned long) _x),                          \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char *),   \
    MAY_STRING_C ((const char*) (unsigned long) _x),                          \
 __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), may_t),    \
    (_x),                                                                     \
 (void)0))))))))))))));                                                       \
 _z; })

5

je vous passe les details sordibes qui surviennent devil

6

[cite] __builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char *), \
MAY_STRING_C ((const char*) (unsigned long) _x), [/cite]
couic

Ca c'est sordide, de supposer qu'un pointeur est un "unsigned long"... C vraiment pas possible autrement?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

7

Ben si je file direct un flottant, ca donne:
MAY_STRING_C ((const char*) 1.2), \

Ben le compilo il aime pas. Il faut que je caste dans un entier avant. Je pourrais utiliser uintmax_t a la place pour etre tranquille.
En pratique, il n'existe que tres peu de systeme ou sizeof(void*) > sizeof(unsigned long). (Perso j'en connais pas).
Tu as lu le code de PARI ?

8

trifus En l'occurence, __builtin_types_compatible_p (typeof (1.2), char *) == 0, non?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

9

Oui mais l'interieur de la branche doit rester semantiquement/syntaxiquement correct.
Ca va surement changer dans les GCC futurs parce que c'est quand meme bien chiant (Cf le nombre de cast que je suis obblige de faire).

10

Ah OK ! Donc en fait __builtin_choose_expr(a,b,c) est équivalent à (a?b:c) pour l'instant?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

11


This built-in function is analogous to the `? :' operator in C,
except that the expression returned has its type unaltered by
promotion rules. Also, the built-in function does not evaluate
the expression that was not chosen. For example, if CONST_EXP
evaluates to true, EXP2 is not evaluated even if it has
side-effects.

This built-in function can return an lvalue if the chosen argument
is an lvalue.

If EXP1 is returned, the return type is the same as EXP1's type.
Similarly, if EXP2 is returned, its return type is the same as
EXP2.
_Note:_ This construct is only available for C. Furthermore, the
unused expression (EXP1 or EXP2 depending on the value of
CONST_EXP) may still generate syntax errors. This may change in
future revisions.

Donc non pas tout a fait, mais presque.

12

OK, donc modulo le fait qu'il n'y a pas d'identification des types de retour (et qu'on a la garantie que le compilo va bien optimiser l'expression comme on veut).

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

13

Oui. Tu veux troller ?

14

Encore une superbe victoire de canard top !
struct zz {
  char *str;
  char a,b,c,d;
};
int toto()
{
  const struct zz *x = &(const struct zz) {.str= NULL, .a = 1, .b=2, .c=3, .d=4};
  return x->a+x->d;
}

mouline par: gcc -O2 -S test.c donne:
        .p2align 2,,3
.globl toto
        .type   toto, @function
toto:
        movb    $1, %dl
        movb    $2, %dh
        movl    %edx, %ecx
        andl    $-16711681, %ecx
        movl    %ecx, %edx
        orl     $196608, %edx
        movl    %edx, %ecx
        andl    $16777215, %ecx
        pushl   %ebp
        movl    %ecx, %edx
        movl    %esp, %ebp
        orl     $67108864, %edx
        subl    $8, %esp
        xorl    %eax, %eax
        movl    %edx, -4(%ebp)
        movl    %eax, -8(%ebp)
        movsbl  -1(%ebp),%edx
        movsbl  -4(%ebp),%eax
        addl    %edx, %eax
        leave
        ret


On applaudit bien fort! beret

15

Et apres y'en a qui dise que les compilateurs optimisent. laught

16

excellent tritop

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

[cite]Pollux :
__builtin_choose_expr (__builtin_types_compatible_p (typeof (_x), char *), \
MAY_STRING_C ((const char*) (unsigned long) _x), [/cite]
couic
Ca c'est sordide, de supposer qu'un pointeur est un "unsigned long"... C vraiment pas possible autrement?

En C99, il y a uintptr_t, mais déjà c'est du C99 et puis les implémentations ne sont pas obligées de le proposer.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

18

PpHd :
Encore une superbe victoire de canard top !
struct zz {
  char *str;
  char a,b,c,d;
};
int toto()
{
  const struct zz *x = &(const struct zz) {.str= NULL, .a = 1, .b=2, .c=3, .d=4};
  return x->a+x->d;
}

mouline par: gcc -O2 -S test.c donne:
        .p2align 2,,3
.globl toto
        .type   toto, @function
toto:
        movb    $1, %dl
        movb    $2, %dh
        movl    %edx, %ecx
        andl    $-16711681, %ecx
        movl    %ecx, %edx
        orl     $196608, %edx
        movl    %edx, %ecx
        andl    $16777215, %ecx
        pushl   %ebp
        movl    %ecx, %edx
        movl    %esp, %ebp
        orl     $67108864, %edx
        subl    $8, %esp
        xorl    %eax, %eax
        movl    %edx, -4(%ebp)
        movl    %eax, -8(%ebp)
        movsbl  -1(%ebp),%edx
        movsbl  -4(%ebp),%eax
        addl    %edx, %eax
        leave
        ret


On applaudit bien fort! beret

Avec TIGCC, j'ai:
.LC0:
	.long	0
	.byte	1
	.byte	2
	.byte	3
	.byte	4
#NO_APP
	.text
	.even
	.globl	toto
toto:
	lea (.LC0:w,%pc),%a0
	move.b 4(%a0),%d0
	ext.w %d0
	move.b 7(%a0),%d1
	ext.w %d1
	add.w %d1,%d0
	rts

smile

Il faudra que tu appliques ça à ton GCC si tu veux avoir du code convenable:
diff -Naur gcc-3.3.3.orig/gcc/c-decl.c gcc-3.3.3.tigcc1/gcc/c-decl.c
--- gcc-3.3.3.orig/gcc/c-decl.c	Sat Sep  6 17:44:14 2003
+++ gcc-3.3.3.tigcc1/gcc/c-decl.c	Thu Feb 19 22:20:00 2004
@@ -3279,6 +3353,21 @@
      tree type;
      tree init;
 {
+  /* (TIGCC) If -fglobal-compound-literals (on by default) is given, for
+     constant constructors, the compound literal is just the constructor itself.
+     For variable constructors, we use the new code, since they have to be
+     created on the stack anyway, and since the new code allows taking their
+     address.  */
+if (flag_global_compound_literals && TREE_CONSTANT (init)) {
+  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+    {
+      int failure = complete_array_type (type, init, 1);
+      if (failure)
+	abort ();
+    }
+
+  return init;
+} else {
   /* We do not use start_decl here because we have a type, not a declarator;
      and do not use finish_decl because the decl should be stored inside
      the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT.  */
@@ -3329,6 +3418,7 @@
     }
 
   return complit;
+}
 }
 
 /* Make TYPE a complete type based on INITIAL_VALUE.
diff -Naur gcc-3.3.3.orig/gcc/c-typeck.c gcc-3.3.3.tigcc1/gcc/c-typeck.c
--- gcc-3.3.3.orig/gcc/c-typeck.c	Tue Dec 23 07:23:32 2003
+++ gcc-3.3.3.tigcc1/gcc/c-typeck.c	Thu Feb 19 22:20:02 2004
@@ -876,7 +873,10 @@
 	}
 
       lvalue_array_p = !not_lvalue && lvalue_p (exp);
-      if (!flag_isoc99 && !lvalue_array_p)
+
+      if (!flag_isoc99 && !lvalue_array_p
+          && !(flag_global_compound_literals
+               && (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) )
 	{
 	  /* Before C99, non-lvalue arrays do not decay to pointers.
 	     Normally, using such an array would be invalid; but it can
@@ -3033,6 +3026,12 @@
 	}
 #endif
 
+      /* (TIGCC) In global compound literal mode, allow the address of a
+	 constructor if all the elements are constant.  */
+      if (flag_global_compound_literals
+          && (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg)))
+	;
+
       /* Anything not already handled and not a true memory reference
 	 or a non-lvalue array is an error.  */
       else if (typecode != FUNCTION_TYPE && !flag
diff -Naur gcc-3.3.3.orig/gcc/flags.h gcc-3.3.3.tigcc1/gcc/flags.h
--- gcc-3.3.3.orig/gcc/flags.h	Sat Jun 21 00:18:40 2003
+++ gcc-3.3.3.tigcc1/gcc/flags.h	Thu Feb 19 22:20:02 2004
@@ -690,4 +690,7 @@
 #define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
   (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
 
+/* (TIGCC) Make compound literals (cast constructors) global for backwards compatibility.  */
+extern int flag_global_compound_literals;
+
 #endif /* ! GCC_FLAGS_H */
diff -Naur gcc-3.3.3.orig/gcc/toplev.c gcc-3.3.3.tigcc1/gcc/toplev.c
--- gcc-3.3.3.orig/gcc/toplev.c	Tue Dec 23 07:28:28 2003
+++ gcc-3.3.3.tigcc1/gcc/toplev.c	Thu Feb 19 22:20:04 2004
@@ -883,6 +883,9 @@
 
 int flag_tracer = 0;
 
+/* (TIGCC) Make compound literals (cast constructors) global for backwards compatibility.  */
+int flag_global_compound_literals = 1;
+
 /* Values of the -falign-* flags: how much to align labels in code.
    0 means `use default', 1 means `don't align'.
    For each variable, there is an _log variant which is the power@@ -1184,10 +1187,14 @@
    N_("Report time taken by each compiler pass at end of run") },
   {"mem-report", &mem_report, 1,
    N_("Report on permanent memory allocation at end of run") },
-  { "trapv", &flag_trapv, 1,
+  {"trapv", &flag_trapv, 1,
    N_("Trap for signed overflow in addition / subtraction / multiplication") },
-  { "new-ra", &flag_new_regalloc, 1,
+  {"new-ra", &flag_new_regalloc, 1,
    N_("Use graph coloring register allocation.") },
+  {"global-compound-literals", &flag_global_compound_literals, 1,
+   N_("Make compound literals (cast constructors) global for backwards compatibility") },
+  {"global-cast-constructors", &flag_global_compound_literals, 1,
+   N_("Make compound literals (cast constructors) global for backwards compatibility") },
 };
 
 /* Table of language-specific options.  */


Et si tu veux avoir le tout carrément optimisé en un return 5;, il faudra attendre la scalarisation des structures qui est implémentée dans la branche de développement tree-ssa.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

19


Et si tu veux avoir le tout carrément optimisé en un return 5;, il faudra attendre la scalarisation des structures qui est implémentée dans la branche de développement tree-ssa.

Je n'en demande pas tant. grin