Type de variable

a marqué ce sujet comme résolu.

Bonjour,

Ici je trouve le code suivant :

int x, y, z;                        //three axis acceleration data
double roll = 0.00, pitch = 0.00;       //Roll & Pitch are the angles which rotate by the axis X and y

void RP_calculate(){
  double x_Buff = float(x);
  double y_Buff = float(y);
  double z_Buff = float(z);
  roll = atan2(y_Buff , z_Buff) * 57.3;
  pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3;
}

Je ne comprends pas bien les lignes :

  double x_Buff = float(x);

Un poil brutal, je voudrais écrire :

  double x_Buff = x;

Est ce correct ou est ce une mauvaise pratique?

Là les variables x, y et z sont des variables globales, je veux les passer en variables locales a la fonction. Je m’aperçois en testant que le code suivant compile et fonctionne (en c):

#include <stdio.h>

void fonction_branlante(double z)
{
    printf("z = %f\n", z);
}

int main(void)
{
    int x = 3;
    printf("x = %d\n", x);
    fonction_branlante(x);
}

J’envoie un int a une fonction qui attend un double. Le compilateur gère ça. Ca marche. Est ce correct ou est ce une mauvaise pratique?

Merci d’avance.

La syntaxe TYPE(variable) est un "cast", c’est a dire un changement de type de la valeur. On peut rencontrer aussi (TYPE)variable.

Mais c’est une syntaxe du C et pas du C++. Parce que en C++, il existe des variables de différentes "natures" (peu importe les détails) et cet syntaxe peut faire des choses complètement différentes selon cette nature. On va préférer en C++ des cast explicites : static_cast, dynamic_cast, const_cast, reinterpret_cast. Cf la documentation.

La syntaxe double x_Buff = float(x); est un peu (beaucoup) étrange. Elle va cast le int en float, puis ce float est cast implicitement en double. Honnêtement, je vois pas de raison a priori de passer par un float (mais je suis pas dev embarqué, il y a peut être une subtilité que je loupe).

Avec ton code double x_Buff = x;, tu laisse le compilateur faire un cast implicite directement de int vers double. A priori, c’est mieux (même en pratique, c’est généralement mieux d’avoir un code explicite).

Perso, j’aurais écris :

const auto x_Buff = static_cast<double>(x);
+0 -0

Bonjour,

Je n’y connais rien en développement embarqué. Par contre je viens de faire un petit test parce que vous m’avez intrigué:

#include<stdio.h>

int main (int argc, char** argv) {
int x = 10;
double d = float(x);
printf("%.3g\n", d);
return 0;
}

Et j’obtiens:

test676.c: In function 'main':
test676.c:5:12: error: expected expression before 'float'
    5 | double d = float(x);
      |            ^~~~~

Autrement dit, float(x) n’est pas du C valide, en tout cas pas pour GCC 13.

A partir de là j’imagine deux possibilités:

  • float(x) est une construction spécifique du compilateur arduino et signifie peut-être reinterpret_cast<float>(x) par opposition à (float)x qui équivaut à static_cast<float>(x).
  • Dans le monde arduino, float n’est pas un type, ni un mot réservé, et c’est donc un appel de fonction classique, qui fait peut-être (ou pas) la même chose que reinterpret_cast<float>(x).

Ni l’un, ni l’autre ne me parait particulièrement déconnant, dans la mesure où le support des nombres flottants est probablement limité ou différent du standard IEE-754 sur de l’embarqué. Simples suppositions.

ET évidemment, mes parallels avec le C++ sont foireuses, car on ne peut sûrement pas faire de C++ sur arduino.

+0 -0

float(x) n’est pas du C, c’est du C++.

Le cast en C++ c’est : static_cast<T>(exp), const_cast<T>(exp), reinterpret_cast<T>(exp) ou dynamic_cast<T>(exp).
Le C++ tolère le cast façon C (T)exp en considérant le 1er ou le 3me cast C++ éventuellement combiné avec le 2nd et y ajoute la possibilité de convertir un pointeur ou une référence vers une classe de base non ambiguë et inaccessible.
Mais le C++ a aussi Type(paramètres) et Type{paramètres} qui est la construction d’une pr-value. Cela revient à faire un cast quand il y a un unique argument, par exemple:

auto  v1 = std::vector<int>(3);  // tableau de 3 éléments nuls
auto  v2 = std::vector<int>{3};  // tableau d'un seul élément valant 3, il pourrait y avoir 0 ou plusieurs arguments.
auto  x3 = float(x);    // création d'un float à partir de x (équiv à cast)
auto  x4 = float{x};    // création d'un float à partir de x sans perte (ne compile pas si x est double ou une constante entière de plus 24 bits significatifs)
auto&& x5 = auto(exp);  // création d'une copie de exp si exp est l-value

float(x) n’est pas du C, c’est du C++.

dalfab

Je viens de vérifier le doc et tu viens de m’apprendre un truc. Je pensais que les 2 syntaxes etaient du C, mais effectivement non.

+0 -0

ET évidemment, mes parallels avec le C++ sont foireuses, car on ne peut sûrement pas faire de C++ sur arduino.

Arduino est basé sur C++ et non C.
Donc il y des classes par exemple.
Aussi, c’est compilé avec avr-gcc, donc on a accès à une bonne parties des extensions GCC.

Aucune idée si la STL est disponible, j’imagine que oui.

+0 -0

OK, alors au temps pour moi, je pensais que c’était vraiment du C uniquement.

Par contre pour la STL, pas sûr, ou peut-être pas complètement. Il me semble avoir vu passer un topic l’autre jour pour gérer un joystick, où quelqu’un a proposé une solution à base de std::map, solution qui a été balayée car pas disponible.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte