Πόσο καλά τα πάει ο gcc με τα templates;
Giorgos Keramidas
keramida at ceid.upatras.gr
Tue May 2 18:30:23 EEST 2006
On 2006-05-02 17:54, Chameleon <cham_gss at hotmail.com> wrote:
> Μπα. Μάλλον είναι αδύνατο να ξαναγυρίσω πάλι στη C. Δεν βολεύει για
> πολύ κώδικα. Βασικά δεν βολεύει για πολλά πράγματα.
>
> "Η C είναι η γλώσσα προγραμματισμού με την οποία προγραμμάτισε ο Θεός
> τον κόσμο"
> "Η C++ είναι η γλώσσα προγραμματισμού των αιρετικών"
> ... από το "OpenGL Programming Guide" στο Glossary.
Αντίστοιχης 'εξυπνάδας' σχόλιο με την πανέμορφη αλλά εξίσου λάθος γνώμη
του Strousstrup για το πνευματικό του παιδί... Τέλος πάντων.
> >> Μεταξύ μας, δεν έχω πάρει ιδέα ποιά είναι η διαφορά μεταξύ gcc, g++
> >> και c++. Όλα το ίδιο δεν κάνουν;
> >
> > Οχι.
> > Το `gcc' είναι C compiler.
>
> πλάκα μου κάνεις τώρα; Και πως έκανα compile κώδικα c++ με gcc;
> α! έτσι εξηγείται που δεν μπορούσα να παράγω εκτελέσιμο! (τα .ο
> παράχθηκαν κανονικά!)
Ναι έτσι εξηγείται. Το GNU C Compiler suite έχει και C++ runtime
βιβλιοθήκες και C runtime βιβλιοθήκες. Προσοχή τι του λες να κάνει,
γιατί θα σε υπακούσει τυφλά, ακόμα κι αν του λες κάτι λάθος :P
> δε μου λες; γιατι είναι τοσο huge (500KBs) ενώ στα Windows είναι τόσο
> small; Κι επειδή πάει και αργά, μάλλον έχει ενσωματώσει debug symbols.
Οχι, γενικά η C++ είναι πιθανόν να παράγει λίγο πιο χάλια εκτελέσιμα.
Ακόμη και σε απλά προγράμματα όπως το "Hello world" μπορεί να δεις
διαφορά, αλλά όχι τόσο μεγάλα binaries όπως λες:
1 | #include <iostream> | #include <stdio.h>
2 | #include <iomanip> |
3 | | int
4 | using namespace std; | main(void)
5 | | {
6 | int | printf("Hello world\n");
7 | main(void) | return 0;
8 | { | }
9 | cout << "Hello world" << endl; |
10 | return 0; |
11 | } |
Μπορείς να τα κάνεις αυτά build με σχετικά μικρό optimization level:
$ cc -O2 -W -Wall -std=c99 -pedantic -o c-hello hello.c
$ c++ -O2 -W -Wall -o cc-hello hello.cc
Οταν τρέχουν αυτά τα 2, οι χρόνοι είναι λίγο υπέρ της C:
$ /usr/bin/time /bin/sh -c 'count=0; \
while test $count -lt 1000 ; do \
./c-hello >/dev/null ; count=$(( $count + 1 )) ; done'
5.06 real 0.82 user 4.21 sys
$ /usr/bin/time /bin/sh -c 'count=0; \
while test $count -lt 1000 ; do \
./cc-hello >/dev/null ; count=$(( $count + 1 )) ; done'
9.81 real 3.08 user 6.64 sys
> Πως μπορώ να παράγω μια πολύ "release" έκδοση; (χωρίς debug symbols)
Με strip(1) στα εκτελέσιμα:
$ ls -l c-hello cc-hello
-rwxrwxr-x 1 giorgos giorgos - 7414 May 2 18:04 c-hello
-rwxrwxr-x 1 giorgos giorgos - 8607 May 2 18:04 cc-hello
$ strip --strip-all c-hello cc-hello
$ ls -l c-hello cc-hello
-rwxrwxr-x 1 giorgos giorgos - 3004 May 2 18:14 c-hello
-rwxrwxr-x 1 giorgos giorgos - 3804 May 2 18:14 cc-hello
$
Πιστεύω 3 ΚΒ είναι πιο λογικό μέγεθος. Μόνο 25% μεγαλύτερο είναι
περίπου το binary της C++ τελικά.
> το makefile είναι αυτό:
> -----------------------
> VPATH = ../src ../example
>
> example1d: wastage1d.o example1d.o
> g++ -o example1d wastage1d.o example1d.o
> wastage1d.o: wastage1d.cpp wastage1d.h
> g++ -c $< -o $@
>
> example1d.o: example1d.cpp wastage1d.h
> g++ -c $< -o $@
> -----------------------
Μην βάζεις 'hardcoded' τιμές σε compiler & flags, γιατί όταν μια μέρα θα
θες να το αλλάξεις αυτό θα βλαστημάς την βιασύνη που σε έκανε να το
γράψεις έτσι. Ενας παλιός κανόνας για makefile writers λέει:
``Οταν κάτι εμφανίζεται πάνω από μια φορά, είναι ώρα να το κάνεις
μεταβλητή.''
Εγώ θα το 'γραφα κάπως έτσι:
1 progname = cc-hello
2 exe_ext =
3
4 prog = $(progname)$(exe_ext)
5
6 $(progname)_sources = foo.cc
7 $(progname)_objs = $(patsubst %.cc,%.o,${$(progname)_sources})
8 objs = ${$(progname)_objs}
9
10 strip_program = strip
11 strip_flags = --strip-all
12 strip_cmd = $(strip_program) $(strip_flags)
13
14 ifeq ($(CCC),)
15 CCC = c++
16 endif
17
18 ifeq ($(CCCFLAGS),)
19 CCCFLAGS = -O2 -W -Wall
20 endif
21
22 all: $(prog)
23
24 clean:
25 -/bin/rm -f $(objs)
26
27 realclean: clean
28 -/bin/rm -f $(prog)
29
30 $(prog): $(objs)
31 $(CCC) $(CCCFLAGS) -o $@ $(objs) $(LDFLAGS) $(LDADD)
32 $(strip_cmd) $@
33
34 %.o: %.cc
35 $(CCC) $(CCCFLAGS) -o $@ -c $^
Ετσι μπορείς να γράψεις π.χ.:
$ gmake realclean
/bin/rm -f foo.o
/bin/rm -f cc-hello
$
Να κάνεις build με τα 'default' options:
$ gmake
c++ -O2 -W -Wall -o foo.o -c foo.cc
c++ -O2 -W -Wall -o cc-hello foo.o
strip --strip-all cc-hello
$
ή με άλλα options, προσωρινά, που σε βολεύουν εκείνη τη στιγμή:
$ gmake realclean
/bin/rm -f foo.o
/bin/rm -f cc-hello
$ env CCC=g++ CCCFLAGS='-O2' gmake
g++ -O2 -o foo.o -c foo.cc
g++ -O2 -o cc-hello foo.o
strip --strip-all cc-hello
$
> Όχι ρε φίλε. Η C++ είναι καλή και αναντικατάστατη.
Μια απίστευτη μπούρδα μεγαλειώδους μεγέθους είναι, αλλά λέμε τώρα.
More information about the Linux-greek-users
mailing list