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

Xcode ne sait pas gérer l'instruction for() !

15 réponses
Avatar
Lionel Mychkine
for(indx = 1; test; indx++)
{
instructions;
}

result = indx - 1;

Ca ne marche pas avec Xcode. Lorsque le test est faux, la variable indx
est quand-même incrémentée ce qui est contraire à tous les standards.

--
Lionel Mychkine

10 réponses

1 2
Avatar
pdorange
Lionel Mychkine wrote:

for(indx = 1; test; indx++)
{
instructions;
}

result = indx - 1;

Ca ne marche pas avec Xcode. Lorsque le test est faux, la variable indx
est quand-même incrémentée ce qui est contraire à tous les standards.



Je suppose que c'est du C et que tu parls du compilateur...
Xcode n'est qu'une environnemnt de développement.

La valeur de indx est incrémenté à chque fois que test est vrai.

Par exemple, en C avec :
int i;
for (i=0;i<;i++)
{
...
}
println(i);

Affichera bien "11" ce qui est normal, puisque quand i, le test étant
vrai, i++ est executé (donc i passe à 11).
La boule suivante étant fausse, i reste bien à 11 en sortie et pas à 12.

Comportement standard des boucles :
<http://en.wikipedia.org/wiki/C_syntax#Iteration_statements>
<http://en.wikipedia.org/wiki/For_loop#C>

Peut être qu'un cas plus concert permettrait de comprendre ton soucis
exact...

--
Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/>

Ce message est sous licence Creative Commons "by-nc-sa-2.0"
<http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
Avatar
Lionel Mychkine
In article <1lc9mus.1y4du2652lhp4N%,
(Pierre-Alain Dorange) wrote:

Lionel Mychkine wrote:

> for(indx = 1; test; indx++)

Je suppose que c'est du C [...]



Il suffit pour s'en convaincre de lire les instructions. Ça aurait pu
être du C++ mais cela ne change rien sur le fond. Dans la vraie vie,
c'est du Cocoa.

et que tu parls du compilateur...



Tu charries ou tu fais l'imbécile ?

La valeur de indx est incrémenté à chque fois que test est vrai.

Par exemple, en C avec :
int i;
for (i=0;i<;i++)
{
...
}
println(i);

Affichera bien "11" ce qui est normal, puisque quand i, le test étant
vrai, i++ est executé (donc i passe à 11).
La boule suivante étant fausse, i reste bien à 11 en sortie et pas à 12.



C'est exactement ce que ne fait pas Xcode. Ou plutôt le compilateur
C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
comprends.

--
Lionel Mychkine
Avatar
Patrick Stadelmann
In article ,
Lionel Mychkine wrote:

C'est exactement ce que ne fait pas Xcode. Ou plutôt le compilateur
C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
comprends.



Donne un vrai programme qu'on peux compiler ainsi que le résultat si tu
veux qu'on considère cette possibilité...

Patrick
--
Patrick Stadelmann
Avatar
pdorange
Lionel Mychkine wrote:

> Lionel Mychkine wrote:
>
> > for(indx = 1; test; indx++)
>
> Je suppose que c'est du C [...]

Il suffit pour s'en convaincre de lire les instructions. Ça aurait pu
être du C++ mais cela ne change rien sur le fond. Dans la vraie vie,
c'est du Cocoa.

> et que tu parls du compilateur...

Tu charries ou tu fais l'imbécile ?



Un peu les 2... Tu ne précise que peu de chose du contexte... Pas de
version, pas de langage...


> La valeur de indx est incrémenté à chque fois que test est vrai.
>
> Par exemple, en C avec :
> int i;
> for (i=0;i<;i++)
> {
> ...
> }
> println(i);
>
> Affichera bien "11" ce qui est normal, puisque quand i, le test étant
> vrai, i++ est executé (donc i passe à 11).
> La boule suivante étant fausse, i reste bien à 11 en sortie et pas à 12.

C'est exactement ce que ne fait pas Xcode.



Disons que je viens de la compiler et que ça m'affiche :

0 1 2 3 4 5 6 7 8 9 10 : 11

Ce qui est plutot normal.
Je précise que j'utilise XCode.

Ca donne quoi chez toi ?

Si dessous le code exact C++ :

#include <iostream>

int main (int argc, char * const argv[]) {
int i;

for (i=0;i<;i++)
{
std::cout << i;
std::cout << " ";
}
std::cout << " : ";
std::cout << i;

return 0;
}

Ou plutôt le compilateur
C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
comprends.



Je comprend ce que l'on veut bien dire, mais si tu veux pas que l'on
essaye d'aider, c'est pas un soucis.

--
Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/>

Ce message est sous licence Creative Commons "by-nc-sa-2.0"
<http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
Avatar
Lionel Mychkine
In article
,
Patrick Stadelmann wrote:

In article ,
Lionel Mychkine wrote:

> C'est exactement ce que ne fait pas Xcode. Ou plutôt le compilateur
> C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
> comprends.

Donne un vrai programme qu'on peux compiler ainsi que le résultat si tu
veux qu'on considère cette possibilité...




#import <Cocoa/Cocoa.h>
#import <CoreAudio/AudioHardware.h>

// la librairie CoreAudio.framework doit se trouver dans le projet
// il faut renseigner outputDeviceID mais en principe, 40 convient

@interface AppDelegate : NSObject <NSApplicationDelegate>

@end

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(NSNotification *) aNotification
{
Float32 volume;
UInt32 channel;
UInt32 propertyDataSize;
AudioObjectPropertyAddress audioPropertyAddress;
UInt32 numberOfChannels;
AudioObjectID outputDeviceID = 40;
OSStatus err = noErr;

audioPropertyAddress.mSelector = kAudioDevicePropertyVolumeScalar;
audioPropertyAddress.mScope = kAudioObjectPropertyScopeOutput;

// ###### CHANNEL EST INCREMENTE MEME SI ERR <> NOERR ######
for(channel = 1; err == noErr; channel++)
{
propertyDataSize = sizeof volume;
audioPropertyAddress.mElement = channel;
err = AudioObjectGetPropertyData(outputDeviceID,
&audioPropertyAddress, 0, NULL,
&propertyDataSize, &volume);
}

numberOfChannels = channel - 1; // ###### ERREUR ########
}

@end

--
Lionel Mychkine
Avatar
Patrick Stadelmann
In article ,
Lionel Mychkine wrote:

In article
,
Patrick Stadelmann wrote:

> In article ,
> Lionel Mychkine wrote:
>
> > C'est exactement ce que ne fait pas Xcode. Ou plutôt le compilateur
> > C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
> > comprends.
>
> Donne un vrai programme qu'on peux compiler ainsi que le résultat si tu
> veux qu'on considère cette possibilité...


#import <Cocoa/Cocoa.h>
#import <CoreAudio/AudioHardware.h>

// la librairie CoreAudio.framework doit se trouver dans le projet
// il faut renseigner outputDeviceID mais en principe, 40 convient

@interface AppDelegate : NSObject <NSApplicationDelegate>

@end

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(NSNotification *) aNotification
{
Float32 volume;
UInt32 channel;
UInt32 propertyDataSize;
AudioObjectPropertyAddress audioPropertyAddress;
UInt32 numberOfChannels;
AudioObjectID outputDeviceID = 40;
OSStatus err = noErr;

audioPropertyAddress.mSelector = kAudioDevicePropertyVolumeScalar;
audioPropertyAddress.mScope = kAudioObjectPropertyScopeOutput;

// ###### CHANNEL EST INCREMENTE MEME SI ERR <> NOERR ######
for(channel = 1; err == noErr; channel++)
{
propertyDataSize = sizeof volume;
audioPropertyAddress.mElement = channel;
err = AudioObjectGetPropertyData(outputDeviceID,
&audioPropertyAddress, 0, NULL,
&propertyDataSize, &volume);
}

numberOfChannels = channel - 1; // ###### ERREUR ########
}

@end



Le comportement est correct, la variable est incrémentée autant de fois
que le test est vrai, car la boucle for est équivalente à

channel=1;
while (err == noErr)
{
{ ... corps de la boucle for ... }
channel++;
}

Dans ton cas, la boucle est au moins exécutée une fois puisque le
premier test est vrai, donc index vaut au minimum 2 en sortie. Il faut
donc soustraire 2 pour obtenir le nombre d'appel à AudioObjectGet... qui
n'a pas généré d'erreur.

Patrick
--
Patrick Stadelmann
Avatar
Patrick Stadelmann
In article ,
Lionel Mychkine wrote:

In article
,
Patrick Stadelmann wrote:

> In article ,
> Lionel Mychkine wrote:
>
> > C'est exactement ce que ne fait pas Xcode. Ou plutôt le compilateur
> > C/C++ dans un environnement Cocoa de Xcode pour parler comme tu
> > comprends.
>
> Donne un vrai programme qu'on peux compiler ainsi que le résultat si tu
> veux qu'on considère cette possibilité...


#import <Cocoa/Cocoa.h>
#import <CoreAudio/AudioHardware.h>

// la librairie CoreAudio.framework doit se trouver dans le projet
// il faut renseigner outputDeviceID mais en principe, 40 convient

@interface AppDelegate : NSObject <NSApplicationDelegate>

@end

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(NSNotification *) aNotification
{
Float32 volume;
UInt32 channel;
UInt32 propertyDataSize;
AudioObjectPropertyAddress audioPropertyAddress;
UInt32 numberOfChannels;
AudioObjectID outputDeviceID = 40;
OSStatus err = noErr;

audioPropertyAddress.mSelector = kAudioDevicePropertyVolumeScalar;
audioPropertyAddress.mScope = kAudioObjectPropertyScopeOutput;

// ###### CHANNEL EST INCREMENTE MEME SI ERR <> NOERR ######
for(channel = 1; err == noErr; channel++)
{
propertyDataSize = sizeof volume;
audioPropertyAddress.mElement = channel;
err = AudioObjectGetPropertyData(outputDeviceID,
&audioPropertyAddress, 0, NULL,
&propertyDataSize, &volume);
}

numberOfChannels = channel - 1; // ###### ERREUR ########
}

@end



Le comportement est correct, la variable est incrémentée autant de fois
que le test est vrai, car la boucle for est équivalente à

channel=1;
while (err == noErr)
{
{ ... corps de la boucle for ... }
channel++;
}

Dans ton cas, la boucle est au moins exécutée une fois puisque le
premier test est vrai, donc channel vaut au minimum 2 en sortie. Il faut
donc soustraire 2 pour obtenir le nombre d'appel à AudioObjectGet... qui
n'a pas généré d'erreur.

Patrick
--
Patrick Stadelmann
Avatar
Lionel Mychkine
In article
,
Patrick Stadelmann wrote:

Dans ton cas, la boucle est au moins exécutée une fois puisque le
premier test est vrai, donc channel vaut au minimum 2 en sortie. Il faut
donc soustraire 2 pour obtenir le nombre d'appel à AudioObjectGet... qui
n'a pas généré d'erreur.



A un moment, et c'est le but recherché, la fonction
AudioObjectGetPropertyData va renvoyer une erreur. La variable channel a
une certaine valeur à ce moment là, valeur dont il ne faut pas tenir
compte puisqu'elle est à l'origine de l'erreur. Et puisque le test
err == noErr sera faux, channel n'a aucune raison d'être incrémenté. En
sortie de for on considère que le nombre de canaux est égal à
channel - 1.

Par exemple, sur un système monophonique l'erreur sera déclenchée sur
channel = 2 et il faut donc soustraire 1 parce que si, comme toi, on
soustrait 2, on obtiendra un nombre de canaux égal à zéro ce qui est
tout simplement faux.

Le problème est que lorsque la variable err est renseignée et donc <>
noErr, channel est quand-même incrémenté et c'est bien ça qui n'est pas
normal.

J'ai dû pour m'en sortir modifier le for() de la façon suivante :

for(channel = 1; ; channel++)
{
propertyDataSize = sizeof volume;
audioPropertyAddress.mElement = channel;
err = AudioObjectGetPropertyData(outputDeviceID,
&audioPropertyAddress, 0, NULL,
&propertyDataSize, &volume);
if(err)
break;
}

Je maintiens que la gestion du for() sous Xcode 5 ne respecte pas les
standards du C et du C++. Cela arrive même aux meilleurs, encore faut-il
le reconnaître.

J'aurais sans doute pu également utiliser une boucle while() pour
contourner le problème comme tu le fais mais l'instruction

for(channel = 1; err == noErr; channel++)

indique très clairement le but recherché et facilite la maintenance.

--
Lionel Mychkine
Avatar
Patrick Stadelmann
In article ,
Lionel Mychkine wrote:

In article
,
Patrick Stadelmann wrote:

> Dans ton cas, la boucle est au moins exécutée une fois puisque le
> premier test est vrai, donc channel vaut au minimum 2 en sortie. Il faut
> donc soustraire 2 pour obtenir le nombre d'appel à AudioObjectGet... qui
> n'a pas généré d'erreur.

A un moment, et c'est le but recherché, la fonction
AudioObjectGetPropertyData va renvoyer une erreur. La variable channel a
une certaine valeur à ce moment là, valeur dont il ne faut pas tenir
compte puisqu'elle est à l'origine de l'erreur. Et puisque le test
err == noErr sera faux, channel n'a aucune raison d'être incrémenté. En
sortie de for on considère que le nombre de canaux est égal à
channel - 1.



Non, la variable est initialisée (première itération) ou incrémentée
(itération suivante) AVANT le test. C'est une question de cohérence : la
valeur de la variable ne doit pas changer entre le test et l'exécution
de la boucle. Elle doit donc forcément changer AVANT le test ! Sinon,
avec i == 9 le test i < 10 serait vrai, mais on exécuterait la boucle
avec i == 10 ! Ca serait tout à fait illogique.

Ton problème c'est que tu initialises ta variable à 1. Dans ce genre de
boucle de comptage, on initialise en général à 0 et on soustrait 1 en
sortie. Si tu initialises à 1, alors il faut soustraire 2.

Je maintiens que la gestion du for() sous Xcode 5 ne respecte pas les
standards du C et du C++.



Tu te trompes.

Patrick
--
Patrick Stadelmann
Avatar
pdorange
Lionel Mychkine wrote:

A un moment, et c'est le but recherché, la fonction
AudioObjectGetPropertyData va renvoyer une erreur. La variable channel a
une certaine valeur à ce moment là, valeur dont il ne faut pas tenir
compte puisqu'elle est à l'origine de l'erreur. Et puisque le test
err == noErr sera faux, channel n'a aucune raison d'être incrémenté. En
sortie de for on considère que le nombre de canaux est égal à
channel - 1.

Par exemple, sur un système monophonique l'erreur sera déclenchée sur
channel = 2 et il faut donc soustraire 1 parce que si, comme toi, on
soustrait 2, on obtiendra un nombre de canaux égal à zéro ce qui est
tout simplement faux.

Le problème est que lorsque la variable err est renseignée et donc <>
noErr, channel est quand-même incrémenté et c'est bien ça qui n'est pas
normal.



pourtant...

Selon
<http://en.wikipedia.org/wiki/C_syntax#Iteration_statements>
ou Microsoft :
<http://msdn.microsoft.com/fr-fr/library/d3e6x17s%28v=vs.90%29.aspx>

la syntaxe :
for (e1;e2;e3) { s; }

se traduit par :
e1;
while (e2) {
s;
e3; }

Dans ton cas, lors que AudioObjectGetPropertyData retourne une erreur,
l'incrémentation est quand même faites (elle l'est toujours à partir du
moment pour une boucle est commencé), ce n'est qu'a la boucle suivante
qu'il y a interruption... C'est... standard.

Essayes de compiler ce type de code avec une VirtualBox sous Linux par
exemple...

Si tu ne veux pas que l'incrément se fasse lors de la boucle qui active
la condition de sortie, il faut faire une interruption bruptale (break)
par exemple.

Dans ton cas, il me semblerait préférable soit utiliser un while, ou un
break commetu le fais ou alors (peut être plus standard) commencer par 0
(c'est pas pour rien que le C a comme référence de base 0) :

for(channel = 0; err == noErr; channel++)
{
propertyDataSize = sizeof volume;
audioPropertyAddress.mElement = channel+1;
err = AudioObjectGetPropertyData(outputDeviceID,
&audioPropertyAddress, 0, NULL,
&propertyDataSize, &volume);
}

numberOfChannels = channel - 1;

On notera que des language plus récents n'ont pas implanté de boucle
"for" de cette manière (init, test, incrément) cela évite des erreurs et
incompréhensions (je pense au python par exemple).

--
Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/>

Ce message est sous licence Creative Commons "by-nc-sa-2.0"
<http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
1 2