Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

initialisation partielle de struct

11 réponses
Avatar
david
Bonjour,

Je me demande pourquoi l'initialisation partielle des 'struct'
en C n'est pas syntaxiquement correcte en C++ et comment le
réaliser :

#include <sys/time.h>

int main (void)
{
struct timeval x = { .tv_usec = 2 };
return x.tv_usec;
}

Merci pour tout éclaircissement,

david

10 réponses

1 2
Avatar
espie
In article <ikq9rm$2e5$, david wrote:
Bonjour,

Je me demande pourquoi l'initialisation partielle des 'struct'
en C n'est pas syntaxiquement correcte en C++



Ta syntaxe, c'est du C99 (norme ISO datant de 99).
La norme du C++ date de 98...

et comment le réaliser :


la ?
initialisation est feminin

Tu ne peux pas.
Met juste une affectation sur la ligne du dessous.


Cette construction est utile en C parce qu'on n'a pas d'objets.
En C++ "non legacy", elle ne sert a peu pres a rien. Classes, constructeurs
et surcharge d'operateurs sont bien plus puissants...


#include <sys/time.h>

int main (void)
{
struct timeval x = { .tv_usec = 2 };
return x.tv_usec;
}



#include <sys/time.h>

int main (void)
{
struct timeval x;
x.tv_usec = 2;
return x.tv_usec;
}
Avatar
James Kanze
On Mar 4, 9:02 am, david wrote:

Je me demande pourquoi l'initialisation partielle des 'struct'
en C n'est pas syntaxiquement correcte en C++ et comment le
réaliser :

#include <sys/time.h>

int main (void)
{
struct timeval x = { .tv_usec = 2 };
return x.tv_usec;
}



La raison est simple : cette syntaxe a été ajoutée dans C99, et
C++ se base sur C90. Et personne ne s'en est occupé pour la
porter dans C++0x. (Autant que je sache, en tout cas.)

Quant à la solution, je ne vois que de wrapper la struct dans
une classe, avec un constructeur. Il y aura slicing si par la
suite tu utilises la classe où une valeur de type timeval est
attendue, mais si tout ce que la classe apporte, c'est les
constructeurs, ce slicing est sans consequence.

--
James Kanze
Avatar
david
James Kanze wrote:
On Mar 4, 9:02 am, david wrote:

> Je me demande pourquoi l'initialisation partielle des 'struct'
> en C n'est pas syntaxiquement correcte en C++ et comment le
> réaliser :

> #include <sys/time.h>
>
> int main (void)
> {
> struct timeval x = { .tv_usec = 2 };
> return x.tv_usec;
> }

La raison est simple : cette syntaxe a été ajoutée dans C99, et
C++ se base sur C90. Et personne ne s'en est occupé pour la
porter dans C++0x. (Autant que je sache, en tout cas.)

Quant à la solution, je ne vois que de wrapper la struct dans
une classe, avec un constructeur. Il y aura slicing si par la
suite tu utilises la classe où une valeur de type timeval est
attendue, mais si tout ce que la classe apporte, c'est les
constructeurs, ce slicing est sans consequence.



D'accord, merci pour les éclaircissements, et pour bien
connaitre les historiques des normes !

david
Avatar
david
Marc Espie wrote:
In article <ikq9rm$2e5$, david wrote:
>Bonjour,
>
>Je me demande pourquoi l'initialisation partielle des 'struct'
>en C n'est pas syntaxiquement correcte en C++

Ta syntaxe, c'est du C99 (norme ISO datant de 99).
La norme du C++ date de 98...


<
>et comment le réaliser :
la ?
initialisation est feminin




Merci pour la lesson de français.


Tu ne peux pas.
Met juste une affectation sur la ligne du dessous.

Cette construction est utile en C parce qu'on n'a pas d'objets.
En C++ "non legacy", elle ne sert a peu pres a rien. Classes, constructeurs
et surcharge d'operateurs sont bien plus puissants...




Même si cela ne plait pas à tout le monde, cela peut quand même
permettre de porter plus rapidement du code C réemployé dans du
code C++.



Merci pour les informations,

david
Avatar
Fabien LE LEZ
On Fri, 4 Mar 2011 10:18:02 +0000 (UTC), david :

Même si cela ne plait pas à tout le monde, cela peut quand même
permettre de porter plus rapidement du code C réemployé dans du
code C++.



Pour transformer du code C en C++, on se retrouve à quasiment tout
réécrire. On n'est plus à quelques détails près.
Si tu veux utiliser du code C, mieux vaut le laisser dans un .c, et
définir une interface pour appeler ce code depuis du C++.
Avatar
ld
On 4 mar, 10:28, (Marc Espie) wrote:
In article <ikq9rm$, david   wrote:
>Bonjour,

>Je me demande pourquoi l'initialisation partielle des 'struct'
>en C n'est pas syntaxiquement correcte en C++

Ta syntaxe, c'est du C99 (norme ISO datant de 99).
La norme du C++ date de 98...

>et comment le r aliser :

la ?
initialisation est feminin

Tu ne peux pas.
Met juste une affectation sur la ligne du dessous.

Cette construction est utile en C parce qu'on n'a pas d'objets.
En C++ "non legacy", elle ne sert a peu pres a rien. Classes, constructeu rs
et surcharge d'operateurs sont bien plus puissants...



plus puissant, moins puissant, impuissant, ... il n'y a pas de
relation d'ordre entre les languages.

Les designed initializers permettent aussi de faire des choses
sympatiques en C. Comme nommer les arguments d'une fonction lorsque
ceux-ci on des types identiques, compatibles ou coercibles, ou leur
assigner des valeures par defaut (comme C++). Ils seront donc les
bienvenus en C++.

a+, laurent
Avatar
espie
In article ,
ld wrote:
Cette construction est utile en C parce qu'on n'a pas d'objets.
En C++ "non legacy", elle ne sert a peu pres a rien. Classes, constructeurs
et surcharge d'operateurs sont bien plus puissants...



plus puissant, moins puissant, impuissant, ... il n'y a pas de
relation d'ordre entre les languages.




Si, quand meme, meme si ca ne me surprend pas que tu penses le contraire.

Les designed initializers permettent aussi de faire des choses
sympatiques en C. Comme nommer les arguments d'une fonction lorsque
ceux-ci on des types identiques, compatibles ou coercibles, ou leur
assigner des valeures par defaut (comme C++). Ils seront donc les
bienvenus en C++.



Par exemple, tout ce qui est expression-template et manipulateurs permettent
de faire la meme chose en C++ avec souvent une syntaxe encore plus sympathique.
Avatar
ld
On 4 mar, 17:33, (Marc Espie) wrote:
In article .com>,

ld   wrote:
>> Cette construction est utile en C parce qu'on n'a pas d'objets.
>> En C++ "non legacy", elle ne sert a peu pres a rien. Classes, construc teurs
>> et surcharge d'operateurs sont bien plus puissants...

>plus puissant, moins puissant, impuissant, ... il n'y a pas de
>relation d'ordre entre les languages.

Si, quand meme, meme si ca ne me surprend pas que tu penses le contraire.

>Les designed initializers permettent aussi de faire des choses
>sympatiques en C. Comme nommer les arguments d'une fonction lorsque
>ceux-ci on des types identiques, compatibles ou coercibles, ou leur
>assigner des valeures par defaut (comme C++). Ils seront donc les
>bienvenus en C++.

Par exemple, tout ce qui est expression-template et manipulateurs permett ent
de faire la meme chose en C++ avec souvent une syntaxe encore plus sympat hique.



comment faire un call-by-name en C++ sans definir une classe by nom
d'argument?

a+, laurent
Avatar
espie
In article ,
ld wrote:
On 4 mar, 17:33, (Marc Espie) wrote:
Par exemple, tout ce qui est expression-template et manipulateurs permettent
de faire la meme chose en C++ avec souvent une syntaxe encore plus


sympathique.

comment faire un call-by-name en C++ sans definir une classe by nom
d'argument?



Parce qu'en C, tu m'expliques comment tu fais des initialiseurs de champs
sans definir la struct qui va avec...
Avatar
ld
On 3 avr, 15:15, (Marc Espie) wrote:
In article .com>,

ld   wrote:
>On 4 mar, 17:33, (Marc Espie) wrote:
>> Par exemple, tout ce qui est expression-template et manipulateurs perm ettent
>> de faire la meme chose en C++ avec souvent une syntaxe encore plus
>sympathique.

>comment faire un call-by-name en C++ sans definir une classe by nom
>d'argument?

Parce qu'en C, tu m'expliques comment tu fais des initialiseurs de champs
sans definir la struct qui va avec...



Ok, voyons la quantite de code pour faire du call-by-name optionel en
C

La fonciton a "wrapper" definie dans une bibliotheque externe
(header):

double signal_sinusoidal(double a, double f, double p, double t);

Le wrapper pour avoir du call-by-name avec valeures par defaut
(header, 11 lignes):

struct signal_sinusoidal_args {
double amplitude, frequency, phase, time;
};

static inline double
signal_sinusoidal_inline(struct signal_sinusoidal_args args)
{
return signal_sinusoidal(args.amplitude, args.frequency, args.phase,
args.time);
}

#define signal_sinusoidal(...)
signal_sinusoidal_inline((struct signal_sinusoidal_args){
.amplitude = 1, .frequency = 1, .phase = 0, .time = 1,
__VA_ARGS__ })

L'utilisation (e.g. main.c):

int main(void)
{
// Discipline "forcee"
printf("sigsin-1 %gn", signal_sinusoidal(.time = 0.2));
printf("sigsin-2 %gn", signal_sinusoidal(.frequency = 100, .time =
10));
printf("sigsin-3 %gn", signal_sinusoidal(.amplitude = 5, .frequency
= 100, .time = 10));
// appel trop "ambigu": warnings excess elements...
// printf("sigsin-4 %gn", signal_sinusoidal(5, 100, 0, 10));
}

gcc -std9 -Wall -pedantic -O3 default-args.c -o named-args -lm

# named-args
sigsin-1 0.951057
sigsin-2 0.587785
sigsin-3 2.93893

Et maintenant en C++ standard, on fait comment pour avoir la meme
chose?? Je pense que c'est possible avec une bonne centaine de ligne
et boot::mpl (en attendant les variadic templates).

a+, laurent
1 2