Newsgroup: it.comp.os.linux.development
Titolo: Invio mail da processo C

Buon giorno a tutti
Spero di non essere OT in questo NG.
Sto scrivendo un processo (ovviamente in C) che, tra le altre cose, deve
inviare
alcune mail.
Qualcuno mi sa indicare le primitive/funzioni/librerie o quant'altro per
mandare
dei messaggi di posta DIRETTAMENTE dal processo e SENZA utilizzare uno
script shell?
Vi ringrazio in anticipo
Giorgio

 writes:
G> Buon giorno a tutti
G> Spero di non essere OT in questo NG.
G> Sto scrivendo un processo (ovviamente in C) che, tra le altre cose, deve
G> inviare
G> alcune mail.
Processo e` un programma in esecuzione. Tu scrivi il programma immagino...
Anyway, devi guardarti la RFC sullo SMTP e usare i socket.
-- 
Gian  | main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Uberto|                        David Korn, 1987 ioccc best one liner 
Lauri |-------------------------------------------------------------------
(aka saint) >>Vedere X-Nospam nell'header - See X-Nospam field in Header<<

 Anyway, devi guardarti la RFC sullo SMTP e usare i socket.
speravo in uan documentazione un po + "dettagliata" e/o semplice..
magari qualcuno che ha avuto problemi analoghi...
comunque grazie
sai dirmi dove reperire "rapidamente" l'ultimo RFC?
grazie

 comunque grazie
puoi dare uno sguardo qui:
http://www.gnu.org/manual/mailutils-0.0.9b/mailutils.html
ciao,
nico

 script shell?
Questo programma C invia un email usando sendmail, e senza invocare
alcuno shell:
/**********************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
char * progname;
void err(char * s)
{
    fprintf(stderr, "%s: %s: %s\n", progname, s, strerror(errno));
    exit(1);
}
int main(int ac, char *av[])
{
    int fd[2], pid, res;
    char * msg = "From: salsi\nTo: salsi\nSubject: prova\n\nprova!\n.\n";
    progname = av[0];
    if( pipe(fd) ) err("pipe()");
    pid = fork();
    if( pid < 0 )  err("fork()");
    if( pid > 0 ){  /* PADRE: invio msg al figlio */
        res = write(fd[1], msg, strlen(msg));
        if( res != strlen(msg) )
            err("write()");
        close(fd[1]);
        wait(&res);
		/* v. "man 2 wait" per la diagnostica su "res" */
    } else {  /* FIGLIO: ricevo msg dalla pipe e dirotto a sendmail */
        if( dup2(fd[0], 0) < 0 ) err("dup2(0)");
        if( execl("/usr/sbin/sendmail", "sendmail", "-t", NULL) )
            err("exec(sendmail)");
    }
    exit(0);
}
/**********************************************************************/
La gestione degli errori e' un po' delicata. Infatti, anche se l'invio
puo' avere successo, nulla vieta che il messaggio rimbalzi al mittente
con un bel "undeliverable mail", che magari ritorna una settimana dopo.
A questo proposito conviene creare un account apposta per il mittente,
e andare a controllare periodicamente se ci sono problemi.
Ciao,
// Umberto Salsi
//
// 
http://digilander.iol.it/salsi
 <-- GnuPG key available here!
// Key fingerprint = B957 FB00 10F5 A770 4A26  2D80 BE2C F6CD 77E9 29AE


acc.. questo si che si chiama "inetrperate lo spirito di un ng".. mille
grazie
proverò il codice quanto prima...
per il momento GRAZIEEEEE
e spero di contraccambiare quanto prima
Giorgio

 uno script shell?
Il modo più standard e più portabile (per chi riconosce l'autorità 
dell'Internet Group, s'intende) è usare SMTP, credo tutti i sistemi di 
posta lo supportino. Credo sia una specie di requisito fondamentale
Non ho mai usato le socket, e la documentazione è molto fumosa, spero 
non contenga troppi errori (e ignoro gli header necessari - beh, 
qualcuno lo saprà):
int sendmail(
 char * lpszSmtpHostName, /* address of STMP server */
 char * lpszFrom,         /* e-mail address of the sender */
 char * lpRecipients[],   /* recipients */
 int nRecipientCount,     /* number of recipients */
 char * lpszMsgBuf        /* message */
)
{
SOCKET scSmtpConnection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in saAddress;
struct hostent heSmtpHost;
struct hostent * lpheTmp;
unsigned long address = inet_addr(lpszSmtpHostName);
if(INADDR_NONE == address)
 lpheTmp = gethostbyname(lpszSmtpHostName);
else
 lpheTmp = gethostbyaddr((char *) & address, sizeof(address), AF_INET);
if(lpheTmp)
 memcpy(& heSmtpHost, lpheTmp, sizeof(struct hostent));
saAddress.sin_family = heSmtpHost.h_addrtype;
saAddress.sin_port = 26 << 8;
saAddress.sin_addr = * (struct in_addr *) heSmtpHost.h_addr;
if(connect(scSmtpConnection, (struct sockaddr *) & saAddress, sizeof
(struct sockaddr_in)) == 0)
{
 /* se Dio vuole, ce l'abbiamo fatta almeno a connetterci */
 /* niente controllo errori, non ne ho proprio voglia */
 char * lpCmdBuf = (char *) malloc(1024);
 int nBufSize;
 int i;
 char * lpszLocalHostName = (char *) malloc(1024);
 gethostname(lpszLocalHostName, 1024);
 /*
  non ditemi che avrei potuto usare fprintf: non tutti i sistemi
  operativi accettano le socket come puntatori validi a file
 */
 nBufSize = snprintf(lpCmdBuf, 1024, "HELO %s\n", lpszLocalHostName);
 send(scSmtpConnection, lpCmdBuf, nBufSize, 0);
 nBufSize = snprintf(lpCmdBuf, 1024, "MAIL FROM:<%s>\n", lpszFrom);
 send(scSmtpConnection, lpCmdBuf, nBufSize, 0);
 for(i = 0; i < nRecipientCount; i ++)
 {
  nBufSize =snprintf(lpCmdBuf, 1024, "RCPT TO:<%s>\n", lpRecipients[i]);
  send(scSmtpConnection, lpCmdBuf, nBufSize, 0);
 }
 send(scSmtpConnection, "DATA\n", strlen("DATA\n"), 0);
 send(scSmtpConnection, lpszMsgBuf, strlen(lpszMsgBuf), 0);
 send(scSmtpConnection, "\n.\n", strlen("\n.\n"), 0);
 send(scSmtpConnection, "QUIT\n", strlen("QUIT\n"), 0);
}
return 0;
}
-- 
Nato nel vizio, morto nel supplizio
Nato nel peccato, ad entrare sia invitato

 e spero di contraccambiare quanto prima
A me piacerebbe vedere piu' spesso spezzoni di codice anche brevi e
incompleti che si leggono in due minuti, ma che esprimono un'ideauzza.
Quello che ho scritto di getto era, ovviamente, una di queste possibili
soluzioni.
P.S. - E' software public domain... :-)


 lpszLocalHostName);
Stamattina ho avuto l'illuminazione divina: tutti i \n a fine riga 
diventano dei \r\n, mi raccomando. Sfido io che il server non mi 
riceveva i comandi


 saAddress.sin_port = 26 << 8;
ri-ooops. La porta è 25 (qui 26 per un test particolare che ho fatto), e 
questo sistema per generare un intero corto in network byte order fa 
semplicemente schifo. Voi non usatelo


  */
No che non avresti potuto, almeno su nessuno dei (pochi) sistemi
che conosco. La funzione socket restituisce un file descriptor (int)
che puo' essere usato con read() e write(), non certo con fread()
e fwrite() che, come hai detto, prendono puntatori a strutture FILE.
A mio avviso e' validissimo l'esempio di Salsi (a patto di
avere installato sendmail o equivalente :-)): perche' ammazzarsi per
reinventare la ruota?
C:\>iao Angelo.

 e htons() e' veramente portabile.
Lo so. Lo usano parecchi altri formati, oltre ai protocolli (vedi PNG)


 writes:
AL> E' una convenzione. Una convenzione non corretta č meglio che nessuna 
AL> convenzione del tutto. Se il prefisso č lpsz so che dev'essere una 
AL> stringa. Mi da' una certa sicurezza
Detto tra noi, e` una convenzione da poveretti in quanto a) se hai per
le  mani cose come  etags o  global hai  un'accesso molto  rapido alla
definizione di  una variabile  e quindi l'inconsistente  (da MS  ne ho
letto almeno  3 definizioni diverse) notazione ungherese  e` inutile e
b) ti sfido a pronunciarne il nome...
D'altro caro  nelle FAQ del  C++ e` detto esplicitamente  che ciascuno
puo` scrivere i nomi delle variabili come gli gira.
Certo che prendere esempio da chi fa merdate come le MFC...
AL> Concettualmente č un array di stringhe, "puntatore a puntatore a 
AL> carattere" non mi suona la proverbiale campana
Puntatori ed array in C sono la medesima cosa. Quindi non e` il 
caso di discutere.
AL> Uffa. La documentazione che ho č quella. Le socket quelle sono.
No. Non e` vero. L'implementazione dei socket (maschile!!!) di Windows
e`  differente  da  quella  di  BSD  e di  Linux  (che  ha  la  stessa
interfaccia di BSD anche se implementazione diversa.
Un paio di esempi al volo :
/**********************************************************
This is required because the idiot Windows uses 
closesocket() instead of the standard close().
**********************************************************/
#ifdef _WIN_
void close( int sock )
{
	closesocket( sock );
	return;
}
#endif
...
/* 
  Under Windows, you have to call the
  WSAStartup to open a socket
*/
#ifdef _WIN_
    WSADATA WSAData;
    WSAStartup(MAKEWORD(1,1), &WSAData);
#endif
 
Per la documentazione a basso  prezzo scaricati un po' di samizdat che
la rete ne e` piena.


 caso di discutere.
Non e' proprio cosi'. 
char* strP;
char  strArr[30];
sizeof(strP) vale 4 (almeno su sistemi a 32 bit)
sizeof(strArr) vale 30.
strP++ funziona
strArr++ mica tanto (e fonte di parecchi grattacapi
nei miei primi esperimenti con il "C":-))
in ogni caso se un array viene passato ad una funzione
"decade" al suo puntatore. Pertanto passare
    char*  strArr[]
    char** strPP
ad una funzione e' esattamente la stessa cosa.
Array e puntatori in "C" sono diversi, ma hanno parecchi punti di
contatto, e questo a volte genera casino. Per questo ho affermato
che ad una funzione e' meglio passare un doppio puntatore: questo
e' quello che fa il compilatore (e magari non ti viene la tentazione 
di fare sizeof(strArr[1]) che indipendentemente da quanto e' lungo
strArr[1] restituisce sizeof(void*) :-))))) ).
C:\>iao Angelo

 In futuro potrebbe non esserlo piu'
Permettimi di dubitarne :-)
In ogni caso se vuoi continuare con questa amichevole beccata
o mi scrivi a casa, o ci spostiamo su ICOD o rischiamo di
essere spediti su it.fan.culo dal resto del NG. :-)
C:\>iao Angelo

> caso di discutere.
AP> Non e' proprio cosi'. 
A naso direi che devi ristudiarti il K&R.
AP> char* strP;
AP> char  strArr[30];
AP> sizeof(strP) vale 4 (almeno su sistemi a 32 bit)
AP> sizeof(strArr) vale 30.
Il fatto che sulla seconda valutazione sappia quanto e` l'area allocata non
impedisce che sia valida una cosa del genere:
char p[30];
char *a=p;
in quanto p  e` il puntatore ai 30 char che  hai allocato nel segmento
text.   Puoi scriver  p[3], *(p+3),  3[p], sono  scritture equivalenti
cosi` come a[2]='E'.
AP> strP++ funziona
AP> strArr++ mica tanto (e fonte di parecchi grattacapi
AP> nei miei primi esperimenti con il "C":-))
E' un puntatore costante, pensaci!!!! L'area di memoria e` allocata
nel data o nel bcc segment, non sullo heap e l'indirizzo e` fisso.
Dovrei vedere come si  comportavano i vecchi compilatori all'epoca del
K&R...
AP> in ogni caso se un array viene passato ad una funzione
AP> "decade" al suo puntatore. Pertanto passare
Nessuna decadenza. passi il puntatore.
AP>     char*  strArr[]
AP>     char** strPP
AP> ad una funzione e' esattamente la stessa cosa.
Nessuno ha detto il contrario.
AP> Array e puntatori in "C" sono diversi, ma hanno parecchi punti di
AP> contatto, e questo a volte genera casino. 
Sono la stessa cosa, e` li` che ti incasini. Solo che alcune cose non
sono modificabili ed il compilatore se ne rende conto.
AP> C:\>iao Angelo
$antocielo che mi tocca leggere :)


Accidenti ragazzi, questo thread e' cascato a fagiuolo, mi e' stato molto
utile.
Il mio programma, pero' dovrebbe anche scaricare automaticamente le email e
processarle ad una ad una.
Chi mi da gentilmente una dritta pure su questo aspetto della questione ?
Ciao,
Francesco

 $antocielo che mi tocca leggere :)
H:\>ai ragione :-)))
C:\>iao Angelo

> nel data o nel bcc segment, non sullo heap e l'indirizzo e` fisso.
AP> Puoi vederlo come un puntatore costante se ti piace, ma un array
AP> NON E' equivalente ad un puntatore.
La frase non era felice. In fase di compilazione arr[30] si traduce in
una  costante (vale  &arr[0])  ad  uso e  consumo  del compilatore  (a
livello di assembler e` una label in DATA se l'array e` inizializzato,
in BCC altrimenti). Poi non e` immagazzinata in nessun posto.
AP> Visto che array e puntatori non sono la stessa cosa, passi l'indirizzo
AP> del primo elemento (ovvero l'array decade a puntatore).
AP> 
http://www.faqs.org/faqs/C-faq/faq/
 (Cap. 6)
E' una frase un po' infelice.  Quello che capita e` che il compilatore
ha  "in mano"  una costante  (array  globale) o  l'offset dallo  stack
pointer  (locale), al  momento di  generare il  codice  della chiamata
mette  "nella chiamata" (o  sullo stack  o nei  registri) o  il valore
esplicito o il risultato di una somma (vado a naso)


 writes:
FSR> Il mio programma,  pero' dovrebbe anche scaricare automaticamente
FSR> le email e processarle ad una ad una.
Ho  del codice che  preleva le  e-mail via  POP, lui  le mette  in una
mailbox Unix ma far partire l'elaborazione separatamente e` banale.


 mailbox Unix ma far partire l'elaborazione separatamente e` banale.
Me lo potresti gentilmente inviare, tale codice ?
Ti ringrazio in anticipo, Francesco

 $antocielo che mi tocca leggere :)
A chi lo dici ! :)
-- 
Posted from  [80.105.34.80] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 ha  "in mano"  una costante  (array  globale)
Quello che capita e' che, al contrario di quanto credi,
un vettore DECADE nel puntatore al suo primo elemento.
Lo standard del linguaggio C, che evidentemente non hai
letto, parla esattamente di "decays" e cita i casi in 
cui questa "decadenza" non avviene.
Scusa, ma prima di meravigliarmi dell'infelicita' delle 
frasi altrui, mi documenterei.


 stai scrivendo funzioni troppo lunghe.
Non sempre.
Le convenzioni sui prefissi aiutano nella lettura del codice
sorgente.  Lo scopo del prefisso non e' quello di fare da 
promemoria (difficile dimenticarsi di 3 bottoni su una finestra),
ma quello di identificare i vari pezzi del tuo software.


 writes:
AL> Quello che capita e' che, al contrario di quanto credi,
AL> un vettore DECADE nel puntatore al suo primo elemento.
Allora spiega per filo e per segno come avviene questa decadenza...


 writes:
AL> Non sempre.
AL> Le convenzioni sui prefissi aiutano nella lettura del codice
AL> sorgente.
Qui rischi di farmi ridere di grosso.
Una convenzione  che non e` fissa  e non migliora  la leggibilita` dei
simboli  (facendoli diventare  difficilmente procnunciabili)  non puo`
essere definita come un metodo generale per migliorare la leggibilita`
di un sorgente . 
Puo`  capitare per  alcuni, per  altri no  (c'e` di  mezzo  un livello
psicologico che non e`  quantificabile se non statisticamente, e anche
qui...).
Se poi  parli di  prefissi concordati in  un gruppo  che identifichino
l'appartenenza ad  una certa unita`  del programma questo e`  un altro
discorso. 


discorso. 
No, il discorso e' esattamente questo.
Se non sbaglio stiamo parlando di convenzioni e gli accordi
presi in un gruppo sono delle convenzioni.  Ma non e'
necessario essere in gruppo.  Ci sono delle convenzioni che
ogni programmatore puo' assumere per conto proprio (assumo
che in tutti i miei programmi "btn" sta per "bottone", "cbx"
sta per combo-box, "tbl" per tabella, ecc... ecc...).
Tra l'altro, una personale decorazione dei nomi, puo'
assurgere a convenzione di gruppo quando ci si incontra e
avere dei significati molto piu' ramificati.
Per esempio, si puo' assumere che i membri interni di una
gerarchia di oggetti inizino per "F", che i parametri
passati alle funzioni inizino per "A", che le variabili di
ciclo inizino con "i", ecc... ecc...

Allora spiega per filo e per segno come avviene questa decadenza...
Subito, padrone.
</POLEMIC MODE ON>
Lo faccio perche' e' Natale e mi sento buono, ma non prima
di aver sottolineato che questa tua pronta spocchiosita' nel
correggere gli altri e' davvero antipatica.  Ti senti pronto
a dire a chiunque "vatti a ristudiare l'argomento", quando
dimostri di capirne poco tu per primo dello stesso
argomento.  La prossima volta, prima di correggere altre
persone che potrebbero saperne piu' di te, abbi la decenza
di assicurarti di avere le spalle ben coperte.
</POLEMIC MODE OFF>
Ma ora, finito l'angolo polemico, veniamo a noi.
Come lo standard stesso del linguaggio afferma, un vettore,
generalmente, decade nel puntatore al suo primo elemento.
Questo significa che scrivere:
char a[20];
char *p = a;
vuol dire inserire in p il valore del puntatore al primo
elemento di a, perche' a, che formalmente ha tipo
"array-of-20-char", subisce la trasformazione del suo tipo
in "pointer-to-char".
Questo accade in tutti i casi, meno che in tre circostanze
specifiche:
1. quando uso "sizeof"
----------------------
Se io pensassi che un vettore e un puntatore sono la stessa
cosa, allora nulla mi vieterebbe di pensare che, dati:
char a[20];
char *p;
varrebbe:
sizeof a == sizeof p
Ma non e' cosi'.
Formalmente, sizeof restituisce la dimensione in byte
occupata dal suo argomento.  
Dato che a NON ha tipo "pointer-to-char", ma
"array-of-20-char", il valore restituito e' 20*sizeof(char)
= 20 (perche' sizeof(char) e' identicamente uguale a 1 sotto
tutte le piattaforme), mentre per il puntatore si ha sizeof
(char*) (che su una piattaforma a 32 bit vale generalmente
4).
2. quando uso l'operatore address-of "&"
----------------------------------------
Per il discorso fatto precedentemente, dato il vettore a e
il puntatore p, si ha che &a non restituisce un
"pointer-to-(pointer-to-char)", ma
"pointer-to-(array-of-20-char)".
I tipi dei puntatori, cioe', sono diversi.
3. quando inizializzo dei vettori con stringhe.
-----------------------------------------------
Scrivere:
char s[] = "andrea";
Vuol dire trattare "andrea" come un vettore, cioe' come
{'a','n','d','r','e','a','\0'} e non come un puntatore, come
normalmente succedere in un'assegnazione del tipo:
char *p = "andrea";
------------------------------------------------------------
Spero di aver esaudito la tua fame di conoscenza, se vuoi
maggiori informazioni, leggi lo standard del linguaggio C o
il K&R II versione.

 A naso direi che devi ristudiarti il K&R.
senza voler sembrare impertinente ;-), forse e' meglio se ci ridai una 
occhiata tu al K&R:
"In C la relazione esistente tra puntatori e vettori e' cosi' stretta 
da consentrire la trattazione simultanea di questi argomenti. [cut] Tra 
il nome di un vettore ed un puntatore esiste pero' una differenza che 
deve sempre essere tenuta presente. Una puntatorre e' una variabili, 
quindi espressioni come pa=a e pa++ (pa e' un puntatore, a un array, 
ndCuni) sono legali. Ma il nome di un vettore non e' una variabile; 
costruzioni come a=pa e a++ sono illegali".
Quindi, vettori e puntatori sono due cose *diverse*.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

essere spediti su it.fan.culo dal resto del NG. :-)
No, che su icod sono troppo popolare :) Se non frega più proprio niente 
a nessuno, volentieri proseguirei in privato
Anzi, followup impostato :)


 ma quello di identificare i vari pezzi del tuo software.
Sono d'accordo. Solo che mi sembra ridicolo usare lpsz,
magari sforzandosi si trova qualcosa di piu' sensato [1].
In ogni caso essendo una convenzione ogniuno adotta quella
che gli pare la migliore. Di sicuro non mi metto a "sfiammare"
per questo :-)
C:\>iao Angelo.
[1] Non ci posso fare niente "long pointer to string zero"
    mi e' antipatica! :-)))

    mi e' antipatica! :-)))
Be', pero' anche questa e' un'intepretazione di parte ;)
"lpsz" e' vicina, come interpretazione, al classico "ASCIIZ"
(che viene usato per identificare, nei PC, l'uso di stringhe
"a la C"), dove la "Z" finale indica la presenza del
terminatore.
Non mi sembra il caso di appigliarsi a questi dettagli ;)
In ogni caso, MS ha convertito il suffisso "lpsz" in "psz"
(il "long" non ha piu' senso) e spinge verso l'uso di
quest'ultimo (Charles Petzold docet).

 utile.
effettivamente è stato un thread fortunato
peccato ch enessuno degli esempi proposti contempla
l'eventualità di invare attach..
;((

 mailbox Unix ma far partire l'elaborazione separatamente e` banale.
potresti inviarlo anche  ame?
grazie

 writes:
AL> Non ho capito dov'e' il soggetto, il predicato e il
AL> complemento oggetto di questo periodo, forse e' colpa del
AL> mio livello psicologico ;)
Notorio che i troll hanno poco cervello...


 utile.
effettivamente è stato un thread fortunato


 mailbox Unix ma far partire l'elaborazione separatamente e` banale.
potresti inviarlo anche  ame?
grazie

 writes:
AL> Non ho capito dov'e' il soggetto, il predicato e il
AL> complemento oggetto di questo periodo, forse e' colpa del
AL> mio livello psicologico ;)
Notorio che i troll hanno poco cervello...
-- 


 utile.
effettivamente è stato un thread fortunato


 mailbox Unix ma far partire l'elaborazione separatamente e` banale.
potresti inviarlo anche  ame?
grazie

 writes:
AL> Non ho capito dov'e' il soggetto, il predicato e il
AL> complemento oggetto di questo periodo, forse e' colpa del
AL> mio livello psicologico ;)
Notorio che i troll hanno poco cervello...
-- 


 mailbox Unix ma far partire l'elaborazione separatamente e` banale.
potresti inviarlo anche  ame?
grazie

 writes:
AL> Non ho capito dov'e' il soggetto, il predicato e il
AL> complemento oggetto di questo periodo, forse e' colpa del
AL> mio livello psicologico ;)
Notorio che i troll hanno poco cervello...
-- 




> si. 
AL> Quella che ho sentito dire io è "se una funzione è più lunga di quindici 
AL> righe di codice, spezzala in due funzioni"
A volte si lascia in una sola funzione (ben sapendo che diventa troppo
grossa) per  aumentare l'efficenza della computazione.  Una chiamata a
funzione in  C fa  2 cose  che fanno perdere  cicli macchina,  crea (e
distrugge in uscita) il frame per le variabili locali ma sopratutto fa
un salto che rompe la localita` del codice.
AL> 1- non conosco il C++. Mai neanche sfiorato da lontano. Sporadicamente
AL>    uso l'estensione .cpp per i programmi in C per beneficiare della
AL>    maggiore pignoleria del compilatore, ma i miei rapporti con il C++ si
AL>    interrompono qui
A me piacciono le funzioni "inline"
AL> implementativi. Alcuni sistemi operativi (non esclusi alcuni Unix, tra 
AL> cui mi pare AIX) nemmeno le hanno di serie le socket
E  ti meravigli  ? I  socket sono  BSD, SysV  ha un  altro  modello di
programmazione  per  il  TCP/IP   (non  mi  ricordo  il  nome,  dovrei
riguardare il Comer).
Non ho capito  con che tono hai  citato il "tutto e` un  file", ma non
importa molto.


 writes:
AL> Come lo standard stesso del linguaggio afferma, un vettore,
AL> generalmente, decade nel puntatore al suo primo elemento.
AL> Questo significa che scrivere:
AL> char a[20];
AL> char *p = a;
Bravo troll, ti sei fatto tener  fermo fintanto che sorge la luce. Hai
fatto esattamente quello che volevo tu facessi.
Hai copiato  con diligenza le faq (che  non mi ha detto  nulla che non
sapessi) ma ed hai dimostrato che di inglese non ci sai poi molto.
"To  decay",  narra il  mio  dizionario  di  inglese (non  vocabolario
italianoo-inglese  e  viceversa),  e`  un  verbo  il  cui  significato
negativo e` un  peggioramento piu` o meno grave  (dall'andare a male a
scadere a qualcosa di inferiore) del soggetto.
Non ho mai visto un  puntatore diventare qualcosa di meno solo perche`
si e` risaliti(*) all'indirizzo del primo elemento.
E  non penso  che  ci siano  ragioni  per considerare  i puntatori  un
qualcosa di inferiore agli array.
Anche se e` nello standard, usare decay e` una scelta poco felice.
(*) a volte non si risale, si mette l'indirizzo come literal...
Bye Bye. 
PLONK


Notorio che i troll hanno poco cervello...
ROTFL !
Capisco che ti rode, ma potevi escogitare qualcosa di meglio
!

Anche se e` nello standard, usare decay e` una scelta poco felice.
Usa "decay" vuol dire usare il termine adatto per esprimere
quel che succede.  Lo standard non l'ha scritto un Gian
Uberto Lauri qualsiasi.  
Comunque, ora stai esprimendo pensieri sconnessi, un delirio
iperbolico, dovuto forse allo sforzo disperato di salire
sullo specchio con le mani insaponate.
Personalmente non ho intenzione di continuare a discutere
con chi ha un muro in testa talmente alto e spesso da non
riuscire a pronunciare le parole "hai ragione, ho detto una
stronzata".

 
Prima di dare del troll a qualcuno forse dovresti dare
un'occhiata ai suoi post precedenti.
Laforgia e' uno che il "C" lo conosce.
C:\>iao Angelo

 quest'ultimo (Charles Petzold docet).
Il nuovo che avanza :-)
C:\>iao Angelo

Il nuovo che avanza :-)
ROTFL ;)

 writes:
AL> "Decadere" significa, anche, perdere questa informazione,
AL> che e' il numero di elementi presenti nel vettore.
Questa e` una cosa che mi e` piaciuta. Una obiezione ben posta, chiara
e motivata. E _qui_ devo proprio dire "Cavoli hai ragione" :).
Va bene che  ci tenevi a farmela arrivare  intatta, ma serviva proprio
imballarla in 116 righe di cartacce :) :) :) :) :)?
Ah,  literal non  e` solo  string literal.  E' una  qualsiasi costante
espressa esplicitamente (in contrappositione alle costanti simboliche).


espressa esplicitamente (in contrappositione alle costanti simboliche)
Ho specificato che bisogna parlare di "literal stringa",
proprio perche' il termine "literal" identifica delle
costanti generiche letterali (che possono essera anche
numeriche).
-- 
Andrea Laforgia
#exclude <windows.h>