Unterprogramm klappt nicht

Gast #2323214
Lesenswert?

Moin

Ich möchte Änderungen an einem ATmega-Port per "griffigem" Unterprogramm 
Namen machen, statt das krytisch im Programm.

So hatte ich mir das gedacht:
1
void Backlight_an(void)     { PORTD |=  (1<<PD4); } // Port PD4 high
2
void Backlight_aus(void)    { PORTD &= ~(1<<PD4); } // Port PD4 low
3
void Backlight_wechsel(void){ PORTD ^=  (1<<PD4); } // Port PD4 high<>low

Aber wenn ich im Programm die Zeilen aufrufe
1
Backlight_an;
passiert nichts. Trage ich dagegen im Programm die Zeile
1
PORTD |= (1<<PD4);
ein, dann funktionierts.

Wo liegt mein Fehler? Es soll doch nur das jeweilige Unterprogramm 
aufgerufen werden und dort die Zuweisung zum Port-D angepaßt werden, das 
kann doch nicht so schwierig sein...

Gruß
Michael
Gast #2323221
Lesenswert?

>passiert nichts.
Was heisst das? Gibt es Compilerfehlermeldungen?

Deine Codestücke sind schon syntaktisch nicht korrekt und sollten eine 
Fehlermeldung geben. Bitte lies ein C-Buch.

Eine Funktion wie die gezeigte muss mit:
1
Backlight_an ();

aufgerufen werden.

Wenn auch bedeutend und im Widersruch zu Deiner Beschreibung ist 
andererseits auch nur diese Kleinigkeit falsch.
Gast #2323242
Lesenswert?

@ Stefan Ernst

>> Deine Codestücke sind schon syntaktisch nicht korrekt und sollten eine
>> Fehlermeldung geben.

>Doch, sind sie.

Nein. Mit dieser Syntax ist kein Funktionsaufruf ausgedrückt.

Kurz mal vor dem schreiben, denken!
Gast #2323258
Lesenswert?

@ Stefan Ernst

>Hab ich ja auch gar nicht behauptet.

Hast Du wohl. Die Ausgangsfrage war ja, warum eine Funktion nicht 
ausgeführt wird, obwohl der TO annahm, dass er syntaktisch korrekt einen 
Aufruf formuliert hat. Das aber hast er nicht getan.

Der Knackpunkt ist hier, das einer bestimmten Zeichenfolge (Syntax) eine 
bestimmte Bedeutung (in diesem Sinne also Semantik) unterstellt wurde. 
Eine nicht so zu deutende Formulierung ist syntaktisch nicht korrekt, 
denn sie kann nicht wie beabsichtigt gedeutet werden. Sie hat eine 
andere Bedeutung.
#2323263
Lesenswert?

Kali schrieb:
> @ Stefan Ernst
>
>>> Deine Codestücke sind schon syntaktisch nicht korrekt und sollten eine
>>> Fehlermeldung geben.
>
>>Doch, sind sie.
>
> Nein. Mit dieser Syntax ist kein Funktionsaufruf ausgedrückt.

"Syntaktisch korrekt" und "Funktionsaufruf findet statt" sind zwei
Aussagen, die nicht besonders viel gemeinsam haben.
Es kann durchaus syntaktisch korrekt sein, und trotzdem kein Aufruf 
stattfinden.

Genau das ist hier der Fall.
#2323267
Lesenswert?

Kali schrieb:
> Der Knackpunkt ist hier, das einer bestimmten Zeichenfolge (Syntax) eine
> bestimmte Bedeutung (in diesem Sinne also Semantik) unterstellt wurde.
> Eine nicht so zu deutende Formulierung ist syntaktisch nicht korrekt,
> denn sie kann nicht wie beabsichtigt gedeutet werden. Sie hat eine
> andere Bedeutung.

?

Eine andere (Be-) Deutung ist doch eben nicht Syntax, sondern Semantik.
Gast #2323276
Lesenswert?

@ Klaus Wachtler

>> Nein. Mit dieser Syntax ist kein Funktionsaufruf ausgedrückt.

>"Syntaktisch korrekt" und "Funktionsaufruf findet statt" sind zwei
Aussagen, die nicht besonders viel gemeinsam haben.

Nun, Du hast das vielleicht anders gemeint: Genau genommen, sind auch 
"Funktionsaufruf ausgedrückt" und  "Funktionsaufruf findet statt" zwei 
verschiedene Dinge.

"Syntaktisch korrekt" und "Funktionsaufruf ausgedrückt" haben da schon 
eher etwas gemeinsam.

Ich denke, schon dadurch, dass oben drüber steht "Syntax eines 
C-Programmes", enthält die Beschreibung dieser Syntax eine Bedeutung. 
Dies kann man herunter auf jeden Ausdruck anwenden der für sich genommen 
eine Bedeutung hat. D.h. es gibt Zeichenfolgen, die einen 
Funktionsaufruf ausdrücken und solche die das nicht tun.
Das führt zu dem weiteren Gedanken, das so etwas wie eine "reine Syntax" 
in diesem Zusammenhang nicht existiert.
#2323279
Lesenswert?

Kali schrieb:
> Der Knackpunkt ist hier, das einer bestimmten Zeichenfolge (Syntax) eine
> bestimmte Bedeutung (in diesem Sinne also Semantik) unterstellt wurde.
> Eine nicht so zu deutende Formulierung ist syntaktisch nicht korrekt,
> denn sie kann nicht wie beabsichtigt gedeutet werden. Sie hat eine
> andere Bedeutung.

Interessanter Versuch, sich rauszuwinden. ;-)
Jetzt finde ich es aber sehr spannend von dir zu erfahren, wie du da nun 
auch noch das "sollten eine Fehlermeldung geben" mit einbaust.
Gast #2323283
Lesenswert?

>Eine andere (Be-) Deutung ist doch eben nicht Syntax, sondern Semantik.

Ich meine, das schon in der Syntax eine Deutung enthalten ist.
Es scheint mir, als wenn allein die Tatsache, das es keine alternative 
Syntax für einen Funktionsaufruf gibt, darauf hindeutet, das man die 
Syntax nicht losgelöst von der Bedeutung betrachten kann. (Insofern ist 
C allerdings ein zwar häufiger aber ein Sonderfall).
Das man als Compilerbauer konstruktiv die Syntaxerkennung von der 
Übersetzung trennt ist nicht so aufzufassen, das dies auch "tatsächlich" 
eine Unabhängigkeit von Syntax und Semantik bedeutet.
Gast #2323290
Lesenswert?

@ Stefan Ernst

>Interessanter Versuch, sich rauszuwinden. ;-)
Danke. ;-)


>Jetzt finde ich es aber sehr spannend von dir zu erfahren, wie du da nun
>auch noch das "sollten eine Fehlermeldung geben" mit einbaust.

Da hast Du mich jetzt erwischt. Es ist zwar völlig willkürlich ob man 
solch einen Fall nun als Fehler oder als eine warnwürdige Situation 
auffasst. Auch für letzteres gibt es sicherlich Argumente. Aber auch 
nach meiner Kenntnis würde das bei den Compilern die ich kenne, eine 
Warnung geben.
#2323294
Lesenswert?

Kali schrieb:
> Ich meine, das schon in der Syntax eine Deutung enthalten ist.

Ob sie enthalten ist oder daneben steht, ist jetzt vielleicht etwas 
philosophisch.
Aber in  jedem Fall heißt der Teil mit der Bedeutung dann "Semantik", 
und nicht mehr  "Syntax".

---

Warum erinnert mich diese Argumentation an meinen Bruder?
Der hat mich bei einer unser diversen Auseinandersetzungen mal ins Bein 
gebissen.
Vor den Eltern mit dem Zahnabdruck konfrontiert, war seine Ausrede: er 
hätte gerade zufällig gegähnt, ich wäre ihm reingelaufen.
Gast #2323309
Lesenswert?

@ Klaus Wachtler

>Ob sie enthalten ist oder daneben steht, ist jetzt vielleicht etwas
>philosophisch.

Da stimme ich zu. Ohnehin, ist nach "den Regeln des Handwerks" die Sache 
klar. Ein Parser würde den Code des TO als syntaktisch korrekt erkennen. 
(Das als auch Antwort auf Deinen Vergleich mit Deinem Bruder). Meine 
Einlassung, das es sich syntaktisch nicht um einen Funktionsaufruf 
handelt, ist demnach die nachträgliche Rechtfertigung meiner unklaren 
Formulierung.

Interessant finde ich das aber schon: Diese Trennung von Syntax und 
Semantik ist eigentlich erstmal nur eine rein konstruktive (beim Bau 
eines Compilers). Aber "philosophisch" betrachtet ist diese Trennung 
nicht vorhanden. Mein Beispiel: "... , das es keine alternative
Syntax für einen Funktionsaufruf gibt," scheint mir dafür ein Beleg zu 
sein.
Denn wenn es keine alternative Syntax dafür gibt, so hat dieser Teil der 
Syntax auch eine "Bedeutung".
#2323355
Lesenswert?

Kali schrieb:
> Aber "philosophisch" betrachtet ist diese Trennung
> nicht vorhanden. Mein Beispiel: "... , das es keine alternative
> Syntax für einen Funktionsaufruf gibt," scheint mir dafür ein Beleg zu
> sein.

Die Syntax hat mit einem Funktionsaufruf nichts zu tun.

Bei der Syntax geht es darum, wie man Zeichen kombinieren kann.
Ob sich daraus ein Sinn ergibt, und wenn ja welcher, hat dann nichts 
mehr mit Syntax zu tun.

Bei C konkret geht es bei Syntax darum, welche Zeichenfolgen zulässig 
sind und wie sie zu Token zusammengefasst werden.

Erst wenn die Token (z.B. ein Name anstatt Zeichenfolgen, oder Klammern 
nicht mehr als Zeichen, sondern als Symbol) auf dem Tisch liegen, wird 
überlegt, ob der Name für eine Variable steht, eine Funktion etc, und ob 
die Klammern zu einem Rechenausdruck gehören, zu einem Cast, zu einer 
Funktionsdeklaration, einem Funktionsaufruf, oder ob sie völliger 
Blödsinn sind.
Das hat aber dann schon nichts mehr mit Syntax zu tun.

Aus http://de.wikipedia.org/wiki/Syntax:
> Unter der Syntax einer formalen Sprache (formale Syntax)
>  – wie etwa Programmiersprachen in der Informatik oder
> Kalküle in der Logik – versteht man ein System von Regeln,
> nach denen erlaubte Konstruktionen bzw. wohlgeformte Ausdrücke
> aus einem grundlegenden Zeichenvorrat (dem Alphabet) gebildet
> werden[6] – wobei von der inhaltlichen Bedeutung der Zeichen>
> abgesehen wird bzw. werden kann.

Ansonsten wäre ja die Semantik arbeitslos.
Gast #2323508
Lesenswert?

>> Aber "philosophisch" betrachtet ist diese Trennung
>> nicht vorhanden. Mein Beispiel: "... , das es keine alternative
>> Syntax für einen Funktionsaufruf gibt," scheint mir dafür ein Beleg zu
>> sein.
>Die Syntax hat mit einem Funktionsaufruf nichts zu tun.

>Bei der Syntax geht es darum, wie man Zeichen kombinieren kann.

Dem kann ich zustimmen. Ich wollte nicht sagen, das man aus der 
Darstellung der Syntax alleine auf die Semantik schliessen kann, dass 
also meine Aussage: 'Aber "philosophisch" betrachtet ist diese Trennung 
nicht vorhanden.' einfach nur seine Umkehrung, d.h. dass die Semantik 
aus der Syntax ableitbar ist, bedeuten soll. Das ist sicherlich nicht 
richtig.

Es geht mir darum, das zwischen Syntax und Semantik gewisse 
Wechselbeziehungen bestehen.

>Ob sich daraus ein Sinn ergibt, und wenn ja welcher, hat dann nichts
>mehr mit Syntax zu tun.

Man spezifiziert doch eine Syntax mit einer bestimmten Absicht. Diese 
Absicht bezieht sich auf die Menge der Bedeutungen die man mit 
Ausdrücken die der Syntax entsprechen, mitteilen können will.

Wenn ich z.B. einem Namen, zwei verschiedene Bedeutungen geben will muss 
ich in der Syntax einen Unterschied einbauen, so das seine Bedeutungen 
unterscheidbar sind, was aber nicht gleichbedeutend damit ist, dass die 
Bedeutung inhaltlich aus diesem Unterschied ableitbar ist.

Dein Satz:
>Die Syntax hat mit einem Funktionsaufruf nichts zu tun.
ist so gesehen, nicht vollständig korrekt.
Die Syntax sagt zwar nichts darüber aus, ob ein Name nun als 
Funktionsaufruf oder als ein Zeiger auf die Funktion zu verstehen ist. 
Aber es muss einen Unterschied im Kontext geben, damit man das eine vom 
anderen unterscheiden kann.

Insofern (und in anderer Hinsicht) wirkt sich die Semantik auf die 
Syntax aus.
#2323530
Lesenswert?

Kali schrieb:
> Dein Satz:
>>Die Syntax hat mit einem Funktionsaufruf nichts zu tun.
> ist so gesehen, nicht vollständig korrekt.

Aber nur so gesehen; richtig gesehen ist mein Satz korrekt :-)

> Die Syntax sagt zwar nichts darüber aus, ob ein Name nun als
> Funktionsaufruf oder als ein Zeiger auf die Funktion zu verstehen ist.
> Aber es muss einen Unterschied im Kontext geben, damit man das eine vom
> anderen unterscheiden kann.

Man könnte eineSprache so konstruieren, daß man einem Namen ansieht, 
wozu er gut ist.
In C ist das aber nicht so.

Natürlich sollte sich aus dem Kontext ergeben, was gemeint ist.
Bei C aber eben nicht aus der Syntax, sondern erst aus der Semantik.

Du kannst dich winden wie du willst, aber die Syntax hat nichts mit der 
Bedeutung der Token zu tun.
Ewiges Leugnen ändert auch nichts an den Tatsachen, und einen C-Compiler 
kannst du auch nicht mit endlosen Debatten zum Übersetzen bewegen.
Magst du nicht einfach mal nachlesen, was Syntax ist? Das würde 
vielleicht die Diskussion etwas erleichtern.

Kali schrieb:
> Es geht mir darum, das zwischen Syntax und Semantik gewisse
> Wechselbeziehungen bestehen.

Warum nicht?
Das ist doch lange kein Grund, die beiden zu vermischen.
Gast #2323535
Lesenswert?

>Natürlich sollte sich aus dem Kontext ergeben, was gemeint ist.
>Bei C aber eben nicht aus der Syntax, sondern erst aus der Semantik.

Das habe ich auch garnicht behauptet.
Ich schrieb z.B.
>Die Syntax sagt zwar nichts darüber aus, ob ein Name nun als
>Funktionsaufruf oder als ein Zeiger auf die Funktion zu verstehen ist.

>Ewiges Leugnen ändert auch nichts an den Tatsachen, und einen C-Compiler
>kannst du auch nicht mit endlosen Debatten zum Übersetzen bewegen.
>Magst du nicht einfach mal nachlesen, was Syntax ist?

Hm. Wieso leugnen? Was leugnen? Keine Ahnung was Du da in den falschen 
Hals bekommen hast. Schade.
#2323916
Lesenswert?

Michael schrieb:
> Ja das wars. Danke
Es funktioniert zwar, aber du bist auf dem besten Weg, dir einen 
grauenhaften Programmierstil anzugewöhnen.

Deswegen:

Kali schrieb:
> Bitte lies ein C-Buch.

Und zwar von Anfang an. Wenn das Kapitel mit den Pointern kommt, kannst 
du es erstmal beiseite legen, aber bis dahin arbeite das gewissenhaft 
durch.

Michael schrieb:
> Unterprogramm

In C gibt es keine Unterprogramme!

Sowas macht man nicht:

Michael schrieb:
> void Backlight_an(void)     { PORTD |=  (1<<PD4); }

Dafür nimmt man Makros:

Martin schrieb:
> Beispielsweise#define Backlight_an    PORTD|=_BV(PD4)
Wobei diese Art schon etwas obsolet ist.

#define Backlight_an    PORTD |=  (1<<PD4)
ist die modernere Schreibweise.

Wenn man das schon in eine Funktion packen will, dann macht man das mit 
EINER und nicht mit drei Funktionen:

void Backlight(char function)
{
   switch (function)
   {
     case 0:
      PORTD &= ~(1<<PD4);
     break;

     case 1:
      PORTD |=  (1<<PD4);
     break;

     case 2:
      PORTD ^=  (1<<PD4);
     break;
   }
}

Die drei Zustände kannst du dann noch "griffig" definieren

#define OFF 0
#define ON 1
#define TOGGLE 2

Und dann: Backlight(ON);


mfg.
#2324259
Lesenswert?

>> Beispielsweise#define Backlight_an    PORTD|=_BV(PD4)
>Wobei diese Art schon etwas obsolet ist.

>#define Backlight_an    PORTD |=  (1<<PD4)
>ist die modernere Schreibweise.

Da soll mir aber einer erklären, was an letzterer Schreibweise 
"moderner" ist. _BV ist ein Makro, welches man wunderbar einsetzen kann 
und laut offizieller Stelle (avr-libc Dokumentation) auch nicht 
"obsolet" ist...


> Oder man markiert die Funktion als inline...
Was aber nur genau so wie das Makro funktioniert, wenn man zusätzlich 
noch das passende (vom Compiler abhängige) Attribut hinzugibt, ansonsten 
ist inline nämlich nur ein Vorschlag an den Compiler. Ob er es 
letztenendes auch macht, ist seine Sache.
#2324296
Lesenswert?

Dominik Honnef schrieb:
> Da soll mir aber einer erklären, was an letzterer Schreibweise
> "moderner" ist. _BV ist ein Makro, welches man wunderbar einsetzen kann
> und laut offizieller Stelle (avr-libc Dokumentation) auch nicht
> "obsolet" ist...

#define _BV(bit) (1 << (bit))

Mit obsolet und modern lag ich vielleicht etwas daneben.

Nichtdestotrotz wird in den Datenblättern die (1 << xx) -Schreibweise 
verwendet. Genauso wie im AVR-GCC-Tutorial.

Ob man es nun so macht oder das _BV -Makro verwendet ist natürlich auch 
Geschmackssache und jedem selbst überlassen. Ich hatte jetzt nicht vor, 
jemandem auf den Schlips zu treten.

Allerdings wird sich ein Anfänger beim Anblick desselben nur die Haare 
raufen, weil er überhaupt nicht weiß, was das soll.

(1 << xx) begegnet einem dagegen andauernd.

Aber das muß man jetzt nicht in den folgenden 27 Posts durchdiskutieren.

mfg.
Gast #2324364
Lesenswert?

Thomas Eckmann schrieb:
> Wenn man das schon in eine Funktion packen will, dann macht man das mit
> EINER und nicht mit drei Funktionen:
>
> void Backlight(char function)
> {
>    switch (function)
>    {
>      case 0:
>       PORTD &= ~(1<<PD4);
>      break;
>
>      [...]
>    }
> }
>
> Die drei Zustände kannst du dann noch "griffig" definieren
>
> #define OFF 0
> #define ON 1
> #define TOGGLE 2
>
> Und dann: Backlight(ON);

Danke für den Hinweis. Ich nehme das auf und werde es künftig so 
umsetzen.
Gruß
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren