ich kompiliere immer gerne u.a. mit den zusätzlichen gcc-Parametern "-pedantic -Wall -Werror -Wextra".
(Je mehr Anfänger man ist, desto strenger muss der Compiler sein... )
Dabei ist mir schon mehrmals Folgendes aufgefallen, ich zeige es euch hier mal am Beispiel von dmenu.
Hier der Links zum source-tree: https://git.suckless.org/dmenu/tree/
In util.h findet sich u.a. folgendes:
Code: Alles auswählen
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
Ausschnitt aus congfig.mk (CFLAGS von mir mit -Werror und -Wextra ergänzt):
Code: Alles auswählen
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Werror -Wextra -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
# compiler and linker
CC = cc
Nun beschwert sich also gcc bezüglich dieser Makros:
Code: Alles auswählen
In file included from dmenu.c:19:0:
dmenu.c: In function ‘calcoffsets’:
util.h:4:38: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
#define MIN(A, B) ((A) < (B) ? (A) : (B))
^
dmenu.c:84:32: note: in expansion of macro ‘MIN’
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
^~~
util.h:4:50: error: signed and unsigned type in conditional expression [-Werror=sign-compare]
#define MIN(A, B) ((A) < (B) ? (A) : (B))
^
dmenu.c:84:32: note: in expansion of macro ‘MIN’
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
^~~
dmenu.c:84:30: error: signed and unsigned type in conditional expression [-Werror=sign-compare]
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
^
In file included from dmenu.c:19:0:
util.h:4:38: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
#define MIN(A, B) ((A) < (B) ? (A) : (B))
^
dmenu.c:87:32: note: in expansion of macro ‘MIN’
if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
^~~
util.h:4:50: error: signed and unsigned type in conditional expression [-Werror=sign-compare]
#define MIN(A, B) ((A) < (B) ? (A) : (B))
^
dmenu.c:87:32: note: in expansion of macro ‘MIN’
if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
^~~
dmenu.c:87:30: error: signed and unsigned type in conditional expression [-Werror=sign-compare]
if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
Code: Alles auswählen
inline int
MAX(int A, int B)
{
return (A > B) ? A : B;
}
inline int
MIN(int A, int B)
{
return (A < B) ? A : B;
}
Code: Alles auswählen
drw.o: In function `MAX':
drw.c:(.text+0x2d): multiple definition of `MAX'
dmenu.o:dmenu.c:(.text+0xcdd): first defined here
drw.o: In function `MIN':
drw.c:(.text+0x35): multiple definition of `MIN'
dmenu.o:dmenu.c:(.text+0xce5): first defined here
util.o: In function `MAX':
util.c:(.text+0x0): multiple definition of `MAX'
dmenu.o:dmenu.c:(.text+0xcdd): first defined here
util.o: In function `MIN':
util.c:(.text+0x8): multiple definition of `MIN'
dmenu.o:dmenu.c:(.text+0xce5): first defined here
collect2: error: ld returned 1 exit status
Makefile:28: recipe for target 'dmenu' failed
make: *** [dmenu] Error 1
Mag mir vielleicht jemand erklären, wieso ursprünglich Makros verwendet wurden und wie sich Makros und Funktionen in diesem Kontext unterscheiden?
Wegen der "inline"-Funktion: Bei einem anderen Programm, bei dem ich MIN/MAX-Makros durch Funktionen ersetzt habe, standen die im Gegensatz zu dmenu nicht in einer extra Header-Datei. Hat es damit zu tun, dass ich hier eine "inline"-Funktion brauche und bei dem anderen Programm nicht?