C-code: nested enumeration

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
Momenteel ben ik bezig van het herschrijven van een groot structured text programma naar C echter loop ik nu tegen een probleem aan waarvan ik niet de juiste zoekterm weet in C.

In de structured text hebben we fixed waardes gedefinieerd op de volgende manier
code:
1
2
3
4
5
6
TYPE current_master :
(
  PRIMARY := 0,
  ALTERNATE := 1
) INT;
END_TYPE


Deze enumeration kan aangeroepen worden in de code via "current_master.ALTERNATE". Nu zoek ik dus eigenlijk in C een manier om hetzelfde te bereiken. Vooral het format met de "." erin is belangrijk zodat ik de makkelijkste vertaalslag kan maken van de ene taal naar de andere.

code:
1
2
3
4
enum current_master{
  PRIMARY=0, 
  ALTERNATE =1
};


De enum hierboven moet aangeroepen worden via "(current_master)PRIMARY" en zal een waarde teruggeven van "0", correct?

Als dit de enige oplossing is, dan zal ik toch de hoofdcode meer moeten aanpassen. Jammere is alleen van de structured text oplossing is dat je geen verschil ziet tussen een structure en deze enum.

Alles is terug te redeneren naar 4

Alle reacties


Acties:
  • +1 Henk 'm!

  • F_J_K
  • Registratie: Juni 2001
  • Niet online

F_J_K

Moderator CSA/PB

Front verplichte underscores

Ik verplaats je vraag even van Client Software Algemeen naar de developers-buren :)

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind' (Terry Pratchett, Eric)


Acties:
  • 0 Henk 'm!

  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 21:46

Mr_gadget

C8H10N4O2 powered

Ik zou een struct gebruiken.

code:
1
2
3
4
Struct current_master{
  int PRIMARY=0, 
  int ALTERNATE =1
};

Acties:
  • +2 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Een enum is de correcte oplossing en je hoeft deze als het goed is niet te casten
C:
1
2
3
4
5
6
7
8
enum Kleur
{
   Rood= 0,
   Blauw = 1
};

int number = Blauw ;
enum Kleur enumValue = Blauw 

Dat hoort gewoon te werken zolang je de enum gedeclareert is.
Als je niet ieder keer enum Kleur variable naam wil typen kan je het ook een typedef geven
C:
1
2
3
4
5
6
7
enum Kleur
{
   Rood= 0,
   Blauw = 1
};
typedef enum Kleur Kleur_t;
Kleur_t kleur = Blauw;


https://en.cppreference.com/w/c/language/enum

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Steefph schreef op dinsdag 22 september 2020 @ 15:43:
Vooral het format met de "." erin is belangrijk zodat ik de makkelijkste vertaalslag kan maken van de ene taal naar de andere.
Kun je iets meer uitweiden over waarom dat noodzakelijk is? Misschien is er wel een andere oplossing.

Het "probleem" van enums is inderdaad dat de identifiers onderdeel van de bovenliggende scope van de enum worden. In C++ kan je dat oplossen door de enum bijvoorbeeld in een namespace te plaatsen

C++:
1
2
3
namespace Color { enum e { Red, Green }; };

//Access by Color::Red/Color:Green

Of in modernere C++ door gebruik te maken van de enum class

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
Woy schreef op dinsdag 22 september 2020 @ 18:37:
[...]

Kun je iets meer uitweiden over waarom dat noodzakelijk is? Misschien is er wel een andere oplossing.

Het "probleem" van enums is inderdaad dat de identifiers onderdeel van de bovenliggende scope van de enum worden. In C++ kan je dat oplossen door de enum bijvoorbeeld in een namespace te plaatsen

C++:
1
2
3
namespace Color { enum e { Red, Green }; };

//Access by Color::Red/Color:Green

Of in modernere C++ door gebruik te maken van de enum class
Had het moeten melden maar, platform waar dit weer op moet gaan draaien heeft alleen ondersteuning voor C geen C++

De code gaat van PLC naar Scada platform. Plc ondersteund de notatie zoals gemeld en Scada moet dus in C. We zijn nog in beginnende fase maar, ik liep tegen dit stukje aan en heb wel wat C ervaring maar ST is m'n normale werkomgeving. Wil de code zo direct mogelijk porten om versie beheer correct te houden. Tevens maakt het onderhouden van de code makkelijker.

Als de oplossing van @Mr_gadget geaccepteerd wordt, ga ik denk ik deze toepassen. Misschien niet het efficients maar, wel onderhoudvriendelijker.

[ Voor 26% gewijzigd door Steefph op 22-09-2020 20:08 ]

Alles is terug te redeneren naar 4


  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Mr_gadget schreef op dinsdag 22 september 2020 @ 16:49:
Ik zou een struct gebruiken.

code:
1
2
3
4
Struct current_master{
  int PRIMARY=0, 
  int ALTERNATE =1
};
Het voorbeeld hier werkt niet trouwens dit is geen C wat geaccepteerd wordt door een compiler.
Je zult het als zoiets moeten schrijven
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct myEnum
{
   int primary;
   int alternate;
} enum1 = {.primary=0, .alternate=1}; //Zonder C99 support moet je de .<text>= declaraties hier weglaten.

struct myEnum enum2 = {0, 1};
struct myEnum enum3 = {.primary=0, .alternate=1}; //dit mag ook mits C99 wordt ondersteunt

//nu werken dingen als
int var1 = enum1.alternate;
var1 = enum2.primary;
var1 = enum3.alternate;

Je zult een van deze opties moeten gebruiken om waardes aan je values in de struct te geven, bij enum1 hoeft de ".primary=, .alternate=" declaratie niet perse dus je zou ook gewoon wat enum2 doet achter het "=" kunnen zetten. https://en.cppreference.c...age/struct_initialization

Compound types (struct) werkt heel erg anders in C dan in je Structured Text helaas, je zal dus altijd door een variable je opties moeten benaderen.

Vanuit het oogpunt van een C/C++ programmeur is een enum hier veel duidelijker maar ik weet niet of er ooit een C/C++ programmeur naar je code zal kijken dat is wel iets dat ik mee zou nemen in mijn redenen om voor het ene of het andere te keizen.

[ Voor 18% gewijzigd door NC83 op 24-09-2020 06:15 ]

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 03-10 16:24

Cassettebandje

SA-C90 TDK

Ik ben het met NC83 eens maar let op dat die laatste aanpak ongebruikelijk en zeer foutgevoelig is. Als je enums een soort van scope wilt geven of collissions wilt voorkomen doe je dat in C door alle keys een prefix te geven.

Acties:
  • +1 Henk 'm!

  • NESFreak
  • Registratie: December 2009
  • Nu online
Wat dacht je ervan om de punt te vervangen door een underscore?

code:
1
2
3
4
5
6
enum CurrentMaster
{
  CURRENT_MASTER_PRIMARY   = 0, 
  CURRENT_MASTER_ALTERNATE = 1
};
typedef enum CurrentMaster CurrentMaster;

In gebruik krijg je dan het volgende:
code:
1
2
3
CurrentMaster cm;
cm = CURRENT_MASTER_PRIMARY;
cm = CURRENT_MASTER_ALTERNATE;

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
NESFreak schreef op donderdag 24 september 2020 @ 07:51:
Wat dacht je ervan om de punt te vervangen door een underscore?

code:
1
2
3
4
5
6
enum CurrentMaster
{
  CURRENT_MASTER_PRIMARY   = 0, 
  CURRENT_MASTER_ALTERNATE = 1
};
typedef enum CurrentMaster CurrentMaster;

In gebruik krijg je dan het volgende:
code:
1
2
3
CurrentMaster cm;
cm = CURRENT_MASTER_PRIMARY;
cm = CURRENT_MASTER_ALTERNATE;
Hier zat ik ook al naar te kijken aangezien ik dit bij een vorig project ook zo heb opgelost maar, wou graag aan de originele notatie vasthouden.
Ik zou dan net zo goed #define kunnen gebruiken lijkt me? Ik heb meerdere (>100) van dit soort structures en zou ze dan beter om kunnen zetten naar een grote #define lijst.

Voor de leesbaarheid, het zal code zijn waar mijn bedrijf 99,9% tijd alleen naar zal kijken en we zijn een grote ST groep. Dus, het moet vooral voor onze groep leesbaar blijven.

Alles is terug te redeneren naar 4


  • NESFreak
  • Registratie: December 2009
  • Nu online
Steefph schreef op donderdag 24 september 2020 @ 09:10:
[...]


Hier zat ik ook al naar te kijken aangezien ik dit bij een vorig project ook zo heb opgelost maar, wou graag aan de originele notatie vasthouden.
Ik zou dan net zo goed #define kunnen gebruiken lijkt me? Ik heb meerdere (>100) van dit soort structures en zou ze dan beter om kunnen zetten naar een grote #define lijst.

Voor de leesbaarheid, het zal code zijn waar mijn bedrijf 99,9% tijd alleen naar zal kijken en we zijn een grote ST groep. Dus, het moet vooral voor onze groep leesbaar blijven.
Voor constantes zijn defines vaak zelfs beter dan een enum. Voor c11 hebben enums niet echt een goed gedefinieerd onderliggend type. Ook is het niet netjes om numerieke operaties op enums uit te voeren.
Iets als een bitflags moet je dus ook zeker niet met een enum oplossen, en ook het optellen en aftrekken van enum waarden moet je nooit doen. Immers, als je twee enum waarden bij elkaar op telt hoeft het resultaat niet een geldige waarde voor je enum te zijn. Development guidelines zoals MISRA verbieden het gebruik van enums op die manier dan ook.

code:
1
2
3
4
5
6
7
8
9
10
typedef uint8_t Options;
#define OPTIONS_OPTION1 ((Options)0x01)
#define OPTIONS_OPTION2 ((Options)0x02)
#define OPTIONS_OPTION3 ((Options)0x04)
#define OPTIONS_OPTION4 ((Options)0x08)
#define DEFAULT_OPTIONS (OPTIONS_OPTION1 | OPTIONS_OPTION3)

Options opt = DEFAULT_OPTIONS;
opt &= (Options)~OPTIONS_OPTION3;
opt |= OPTIONS_OPTION2;

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
NESFreak schreef op donderdag 24 september 2020 @ 09:53:
[...]
Voor constantes zijn defines vaak zelfs beter dan een enum. Voor c11 hebben enums niet echt een goed gedefinieerd onderliggend type.
Dat hoeft ook niet, het is de bedoeling dat je de enum gebruikt en niet het onderliggende type.

De situatie die de TS beschijft is precies waar een enum voor is bedoeld; een macro is hier niet de betere oplossing.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
Allen bedankt voor de input. Ik heb met behulp van een simpele excel alles omgezet naar define regels waarbij de punt is vervangen door een underscore.

Alles is terug te redeneren naar 4


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Steefph schreef op donderdag 24 september 2020 @ 21:46:
Allen bedankt voor de input. Ik heb met behulp van een simpele excel alles omgezet naar define regels waarbij de punt is vervangen door een underscore.
Mijns inziens past het beter om niet 1 grote lijst van macro's te genereren maar voor elke ST enum een C enum te maken.

Voor de lezer is het dan iig een stuk duidelijker welke waarden waar van toepassing zijn. Type checking krijg je helaas niet in C voor enums, maar afhankelijk van de compiler zou je een warning kunnen krijgen als je enums naar elkaar converteert (Voor clang is dat -Wenum-conversion, gcc is jammer dan ....)

Ik ben trouwens wel benieuwd wat de casus is van het omzetten van PLC code naar C in een Scada?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
farlane schreef op donderdag 24 september 2020 @ 22:40:
[...]

Ik ben trouwens wel benieuwd wat de casus is van het omzetten van PLC code naar C in een Scada?
De nieuwe trend in procesbesturing helaas. Wij leveren besturing voor turbo-machinery (turbines/compressors) en we hebben onze zelf ontwikkelde plc hiervoor. Nu willen nieuwe klanten graag onze software op hun scada systeem. Helaas betreed je dan de wirwar van talen die gebruikt worden. Zo is er zelfs een scada system dat gebouwd is op VisualBasic met maximale variable naam van 8 characters .

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Steefph schreef op donderdag 24 september 2020 @ 22:51:
De nieuwe trend in procesbesturing helaas. Wij leveren besturing voor turbo-machinery (turbines/compressors) en we hebben onze zelf ontwikkelde plc hiervoor. Nu willen nieuwe klanten graag onze software op hun scada systeem. Helaas betreed je dan de wirwar van talen die gebruikt worden. Zo is er zelfs een scada system dat gebouwd is op VisualBasic met maximale variable naam van 8 characters .
Hmmokay. Maar is die code dan onderdeel van de procesbesturing? Ik bedoel, een PLC is een realtime apparaat terwijl een SCADA iha op een niet-realtime OS draait...

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
farlane schreef op vrijdag 25 september 2020 @ 08:32:
[...]

Hmmokay. Maar is die code dan onderdeel van de procesbesturing? Ik bedoel, een PLC is een realtime apparaat terwijl een SCADA iha op een niet-realtime OS draait...
Dat is precies het probleem waar wij tegen aanlopen maar, het is de nieuwe generatie van engineers bij eindgebruikers die alles in 1 willen hebben gedreven door kosten. Losse plcs zijn duurder in aanschaf en gebruik in vergelijking met alles onderbrengen in 1 systeem. En de hoofdengineer is tegenwoordig de financiële man achter z'n excel-sheet ;)

Onze eigen systemen hebben response tijden van 5ms terwijl dit SCADA systeem richting de 180ms gaat. Dit betekend dat we extra aggresief moeten tunen met meer veiligheidsmarges.

Alles is terug te redeneren naar 4


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Steefph schreef op vrijdag 25 september 2020 @ 09:17:
[...]
Onze eigen systemen hebben response tijden van 5ms terwijl dit SCADA systeem richting de 180ms gaat. Dit betekend dat we extra aggresief moeten tunen met meer veiligheidsmarges.
Responsetijden zijn een ding, maar ik zie ook zaken als machine -en nog belangrijker persoonsveiligheid in het gedrang komen op deze manier....

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 23-09 12:24
We gaan best off topic maar,

Persoonsveiligheid zal ook altijd in een ander systeem gedaan worden om de SIL3/4 rating te kunnen halen. Daarbij zijn er sterke procedures die toegang tot de machines verbieden in productie.

Machine veiligheid heeft op die manier ook extra hardware om de veiligheid te vergroten maar, bij sommige productie lijnen wordt de veiligheid van de machine ondergeschikt gemaakt aan het proces zelf. Denk hierbij aan katalyst dat niet stil mag komen te vallen in een 3jr durend process. Als dit stil valt ben je zo >15mln aan kosten verder en dat is alleen nog maar het katalyst zelf. Alle buizen in de lijn moeten schoongemaakt worden. Run to destruction ;)

Vaak staan er dan ook meerdere van deze machines parallel en starten ze de 1 als de ander faalt.

Alles is terug te redeneren naar 4

Pagina: 1