Newsgroup: it.comp.lang.c++
Titolo: include

Quanto è standard la direttiva include?
La seguente causa problemi di portabilità?
#include "..\conv_tables.h"
Kiuhnm

 #include "..\conv_tables.h"
2.8 [lex.header] .2
"[...] If either of the characters ' or \, or either of the character 
sequences /* or // appears in a
qcharsequence or a hcharsequence, or the character " appears in a 
hcharsequence,the behavior is undefined.[...]"
direi che il problema è di un ordine superiore a quello della portabilità.
-- 
sbi 

 direi che il problema è di un ordine superiore a quello della portabilità.
Vabbe', rilancio con
"../conv_tables.h"
Kiuhnm

 "../conv_tables.h"
Standard, come venga cercato il file è tuttavia dipendente 
dall'implementazione,
se non è possibile ricercare il file per l'implementazione, la direttiva 
viene
considerata come un #include <q-char-sequence> newline.
Notare come in
16.2.3 (#include "q-char-sequence" newline) si parli di source file mentre 
in
16.2.2 (#include <h-char-sequence> newline) si parli soltanto di header che
potrebbe esistere a prescindere dall'esistenza del concetto "file".
Volevi mica far notare questo?:
"The implementation provides unique mappings for sequences consisting of
one or more nondigits followed by a period (.) and a single nondigit.
The implementation may ignore the distinctions of alphabetical case."
... non te la prendere con me. . :)
-- 
sbi 

 considerata come un #include <q-char-sequence> newline.
Ma io ho chiesto se è "portabile".
Il problema non è solo che la ricerca è implementation-defined, ma più 
che altro che "how the places are specified or the header identified is 
implementation-defined." (16.2.2)!
Sarebbe come se ogni server usasse url implementation-defined!
Kiuhnm


E' portabile. L'implementation defined significa che non è garantito che 
i file debbano avere il nom eche pensi tu.
Se nel codice tu scrivi:
#include "a"
l'implementation defined significa che se un compilatore dice che il 
file incluso è quello che, nel suo sistema, ha per nome './a' (unix), 
un'altro dice che nel suo sistema è il file '.\A' (DOS) e un altro che è 
quello che sul suo sistema si chiama '.:a' (per esempio i vecchi mac 
usavano : come separatore delle directory, anche se non esisteva . come 
directory corrente) e un'altro, ipoteticamente, dice che lui usa il file 
'°CURRENTPATH§0060' (nota che 0060 è l'unicode di 'a' espresso in 
esadecimale), allora tutti i suddetti compilatori sono validi e conformi.
Nel caso del sistema ipotetico, se il sistema ammette sia nomi tipo 'a' 
che nomi tipo '0060', sta a te nominare il file correttamente (ed 
eventualmente metterlo nella direcoty giusta, sempre che il sistema 
abbia un concetto di directory).
Nota che persino il concetto di directory locale e di nome di file sono 
solo teorici. Immagina un compilatore che non legge i sorgenti da un 
file ma da un campo testuale di un database SQL. Cosa significa un 
include? In quale database, tabella, riga e colonna deve andare a 
cercare il sorgente incluso?
Risposta: dipende dall'implementazione. Il sorgente dell'header dovrai 
caricarlo TU nel posto corretto in cui l'implementazione mappa 'a'.

 #include "a"
Ho scritto
#include "..\inc.h".
E' ben diverso.
Kiuhnm

 E' ben diverso.
in cosa è diverso? :)
-- 
sbi 


Se usi il \ è undefined. Il che significa che il tuo programma non è 
corretto.
Se usi il / invece il programma è corretto. Il codice è portabile. Dove 
viene preso il testo che costituisce il file incluso è implementation 
defined.

 defined.
Secondo me non è propriamente così.
In pratica vedo che tutti i compilatori (versione Amiga, C64, ecc...) 
supportano le directory in questo stesso stile.
Se così non fosse, si potrebbero avere due percorsi che, pur indicando 
due file diversi in una certa implementazione, indicherebbero lo stesso 
file in un'altra. A questo punto sarebbe necessario modificare il codice 
sorgente.
Kiuhnm

 sorgente.
Altro esempio: in Windows non è possibile avere un file il cui nome 
contenga '?', quindi sarà impossibile rinominare un file in modo che
#include "prova?.h" lo trovi.
Si può quindi concludere che include rende il codice NON portabile.
Kiuhnm

 sorgente.
In teoria si e no.
La questione comunque non riguarda lo standard del linguaggio.
Se il programmatore è abbastanza accorto da scrivere nomi che, in 
presenza di una gerarchia, sono solo discendenti (ovvero eviti l'uso di 
'.' e soprattutto di '..' e non metti '/' come primo carattere) il 
problema non esiste. Altrimenti ... è un problema tuo e non del linguaggio.

 Si può quindi concludere che include rende il codice NON portabile.
In ogni caso non è l'include che ha questo problema ma 
l'implementazione. Un compilatore C++ per windows dovrebbe, in teoria, 
specificare esattamente come mappa i nomi degli include e accettare 
tutte le sequenze valide.

 tutte le sequenze valide.
Lo standard dice che è "implementation defined" e tu mi dici che non è 
colpa dello standard, ma dell'implementazione? Suvvia, non scherzare :)
Kiuhnm

 problema non esiste. Altrimenti ... è un problema tuo e non del linguaggio.
Non si cambiano le regole del gioco a metà partita. Sabbiamo bene 
entrambi cosa significa portabilità, implementation-defined, ecc...
Kiuhnm

 colpa dello standard, ma dell'implementazione? Suvvia, non scherzare :)
Non scherzo. E forse tu non hai capito cosa intendo.
A parte il fatto che sono abbastanza convinto che sia possibile (anche 
se difficile) creare un file il cui nome contiente il ? anche sotto 
windows, il problema non si sposta.
Se windows non permette di creare cotale file, un compilatore per 
windows deve rimappare un nome di file specificato negli include e 
contenete il ? in un altro nome che sia univoco e valido per windows. 
Come avviene questa mappatura non è un problema dello standard ma 
dell'implementazione.


Non cambio nessuna regola.
Ripeto: se la sequenza di caratteri è diversa, deve poter essere mappata 
a file diversi.
Se il tuo sistema non lo permette allora è una limitazione 
dell'implementazione, non dello standard.
Le regolette che citavo sopra (+ altre che mi sono dimenticato: l'uso di 
sole lettere minuscole e la limitazione a nomi 8.3) sono quelle che 
rendono agevole per il programmatore assicurarsi un comportamento 
portabile anche se l'implementazione e/o il sistema hanno delle limitazioni.
Lo standard rende possibile scrivere codice portabile e implementazioni 
in grado di compilare codice portabile. Lo standard non ti obbliga a 
scrivere codice portabile ne a scrivere una implementazione in grado di 
compilarlo. E' possibile scrivere una implementazione conforme che è in 
grado di compilare qualunque codice conforme. Possibile. Non 
obbligatorio. Una implementazione può essere conforme e nello stesso 
tempo non riuscire a compilare codice conforme.

 dell'implementazione.
Ho già spiegato nei primi post perché "include" non è portabile, quindi 
non ho voglia di ripetermi. Lasciamo perdere.
Kiuhnm

 dell'implementazione, non dello standard.
E' impossibile discernere un'implementazione limitata da una non 
limitata perché lo standard non dà alcuna definizione di 
"implementazione limitata".
Kiuhnm