Hello,

Je regardais un peu la tronche du code généré par DMD (v2.064), compilé en release, avec infos de debug.
Au niveau des options de compilation, j'ai testé avec et sans "Run optimizer", avec et sans "Expand inline functions", et le résultat est le même.

Et il y a deux / trois trucs que je comprends pas vraiment
Code D : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Foo {
 
	// ...
 
	public static auto table() {
		static auto t = makeTable!(Foo, "data1", "data2")();
		return t;
	}
}
 
immutable(SqlTable!T) makeTable(T, Q...)() {
	SqlColumn!T[] columns;
	foreach(arg; Q) {
		columns ~= makeColumn!(T, arg)();
	}
	return new SqlTable!T(T.stringof, columns);
}

En D, toute les fonctions sont virtuelles par défaut et le compilo se débrouille (pour simplifier la vie du développeur et normalement parce qu' le compilo sait mieux que nous si une doit être virtuelle ou pas).

Aucune classe ne dérive de Foo, il n'y à aucune utilité à avoir Foo.table() virtuelle, et vu la fonction elle "devrait" donc être inline.

Ici elle n'est pas virtuelle, mais pas inlinée.

DMD génère ceci :
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
_TEXT:004020A8 ; sqlite3@SqlTable!(Foo)@SqlTable *__pascal main_Foo_table()
_TEXT:004020A8 main@Foo@table  proc near               ; CODE XREF: sqlite3@SqliteDB@insert__class_main@Foo_@insert+7p
_TEXT:004020A8                                         ; sqlite3@SqliteDB@prepareStatement__class_main@Foo_@prepareStatement+5p ...
_TEXT:004020A8                 mov     eax, ds:main@Foo@table@
_TEXT:004020AD                 retn
_TEXT:004020AD main@Foo@table  endp
Pourquoi générer une fonction pour ça ?

Dans l'exe on retrouve aussi la fonction makeTable, qui n'est jamais appelée (et rien n'y fait référence), quelle peut être la raison d'inclure du code inutile ?

Concernant la fonction Foo.table(), en la changeant de
Code D : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
public static auto table() {
	static auto t = makeTable!(Foo, "data1", "data2")();
	return t;
}
// à
public static auto table() {
	return makeTable!(Foo, "data1", "data2")();
}

DMD génère
Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
_TEXT:00402068 ; sqlite3@SqlTable!(Foo)@SqlTable *__pascal main_Foo_table()
_TEXT:00402068 main@Foo@table  proc near               ; CODE XREF: sqlite3@SqliteDB@insert__class_main@Foo_@insert+7p
_TEXT:00402068                                         ; sqlite3@SqliteDB@prepareStatement__class_main@Foo_@prepareStatement+5p ...
_TEXT:00402068                 push    eax
_TEXT:00402069                 call    sqlite3@makeTable__class_main@Foo__immutable_char_____data1_c__immutable_char_____data2_c_@makeTable
_TEXT:0040206E                 pop     ecx
_TEXT:0040206F                 retn
_TEXT:0040206F main@Foo@table  endp

On retrouve ici un appel à makeTable, mais encore une fois, pourquoi elle n'est pas inliné ? Et pourquoi cela génère un appel à makeTable ? Le fait d'avoir des données immutable ne devrait pas rendre cet appel inutile ?

L'optimisation prématurée c'est mal, mais j'aimerai juste comprendre pourquoi le code généré est ainsi.