gennaio 2005 Blog Posts
Da questo post del mio connazionale Radu Grigore, scopro un bellissimo teorema di McEliece (per la cronaca, Robert McEliece è stato negli anni '60 compagno di dottorato di ricerca con Donald Knuth, vero mostro sacro dell'informatica):
Any continuous strictly increasing function f : R -> R with the inverse g, g(Z) included in Z, has the dual properties:
ceiling(f(x)) = ceiling(f(ceiling(x)))
floor(f(x)) = floor(f(floor(x)))
OK, adesso so che volete un esempio semplice in C# :-)
System.Math.Sqrt è definita in {double non negativi} con valori in {double non negativi}, è
monotona strettamente crescente strettamente ascendente (si dice così?) e per argomenti interi non negativi...
using System;using System.Threading;class Foo{ static void Main() { try { try { try { Thread.CurrentThread.Abort(); } catch { Console.Write(1); } finally { Thread.ResetAbort(); } } catch { Console.Write(2); } } catch { Console.Write(3); } }}
Cosa viene visualizzato a console e perché?
A. niente
B. errore a run-time
C. 1
D. 12
E. 123
Lasciate le vostre risposte, come al solito, nei commenti.
Il quiz è apparso in variante ovviamente C++ alla pagina 830 nel suo ormai dimenticato libro "Programming Applications for Microsoft Windows"
int FuncaDoodleDoo(){ int temp = 0; while(temp < 10) { try { if(temp == 2) continue; if(temp == 3) break; } finally { temp++; } temp++; } temp += 10; return temp;}
e chiede: "Can you determine what the following function returns?".
Mi raccomando, nei commenti non rispondete solo con sì e no :-)
Un pezzo di storia: nel video di questo post, dal minuto 6:13 al minuto 10:28, Brian Grunkemeyer racconta come gli è venuta l'idea delle classi statiche. E' iniziato tutto da un suo bug nella versione 1.0 del Framework: il metodo System.Environment.HasShutdownStarted non era ai tempi static, e quindi poteva essere chiamato solo tramite reflection :-)
Lo racconta anche in SLAR, alla pagina 178
Vi ricordate di questo post di M.rkino? Ebbene domani si compiono gli anni: 10 dalla prima risposta di Raffaele su un newsgroup!
Grazie mille Raf! Proprio mille.
Alla fine sono riuscito a individuare le opzioni giuste per compilare un programma vuoto (Foo.cpp) in Visual C++ .NET:
cl /CLR /LD Foo.cpp /link /NOENTRY
Lo schema dei colori corrisponde a quello del post precedente. Aggiungo sotto, altri 4 commenti ai 4 precedenti:
il codice IL più pulito per i programmi vuoti è generato dal compilatore Visual C# .NET (a parte, ovviamente, quello corrispondente all'IL stesso);
la dimensione della DLL per Visual C++ .NET è identica a quella della DLL per JScript .NET: 3584 bytes (coincidenza, secondo me, pazzesca! - anche perché gli IL sono diversi)
la direttiva .permissionset ha associata la SecurityAction RequestMinimum (System.Security.Permissions.SecurityAction.RequestMinimum)....
On Topic: Che legame c'è tra il linguaggio BASIC e Albert Einstein?
Off Topic: Ma tra Albert Einstein e Silvio Berlusconi?
I link interessanti che trovo in giro, da un po' di tempo li "furlo" qui (l'RSS del mio furl è questo), risparmiando così lo spazio del blog e la vostra attenzione per cose magari più originali. Però questo, "The Faces in Front of the Monitors", è troppo atipico per non postarlo. Nella scelta dei personaggi (che mischia buoni e cattivi) scopro non pochi nomi giovanissimi...
Me l'ha mandato il mio amico Nicola Venditti, che ogni tanto si ricorda del mio debole per la storia.
E mi sveglio quiin un giorno ad esttra questa nebbia di provinciasogno oppure èe mi lascio quisenza una bugiae mi fa freddo nella nottesembra casa miaAscolto un respiro viene verso meil volto è un nemico e non so mai perchèIo non sono quiin cima a questa viaad ogni punto delle stelle vedo casa miae non mi sveglio piùbevo al tuo caffètutta la notte terra rossa dietro memi manca il respiro e non sei con mema il volto è un nemico e mi dirà perchèsiamo fatti cosìsiamo fatti cosìsiamo nati per giocopersi in questa atmosferaarrivederciarrivederciarrivederci terra straniera
La Nannini
Non è detto che per leggere un file di configurazione (per esempio un web.config) di un'altra applicazione, bisogna per forza utilizzare le classi XML. Basta essere folli e scrivere una cosa come questa qui sotto, sparata oggi - e di cui ne sono contento :-)
In una web application Test, che ha questo web.config:
<?xml version="1.0" encoding="utf-8" ?><configuration> <appSettings> <add key="fooMessage" value="Hello World!" /> </appSettings></configuration>
aggiungiamo questa classe:
using System;using System.Configuration;using System.Collections.Specialized;namespace Ugidotnet.Configuration{ public sealed class CrossConfigSetter { private CrossConfigSetter(){} public const string DataName = "AppSettings"; public static void SetAppSettingsData() { NameValueCollection serializableAppSettings = new NameValueCollection(ConfigurationSettings.AppSettings); AppDomain.CurrentDomain.SetData(DataName, serializableAppSettings); } }}
mentre nella console application da...
La lanterna che illumina il quadro non è quella che tiene Caravaggio in mano a destra, sopra la testa del soldato di cui si vede sotto la nera corazza solo il naso e il culo in stoffa rossa. I capelli di San Giovanni sono gli stessi del Cristo e già un pezzo del suo vestito è in mano a un altro soldato. Grida e si mette in fuga. Agitati i 3 soldati e i 3 uomini. Curiosi solo Caravaggio che tiene la lanterna e noi, i visitatori della mostra. Se leggete questo post in tempo, andate lì per non perderla...
Anche se in IL assembly una classe non eredita esplicitamente da [mscorlib]System.Object, se non specificata, questa ereditarietà è implicita anche a quel livello. Perciò:
.class A{}
viene trasformata dall'assembler in:
.class private auto ansi A extends [mscorlib]System.Object{}
Così, il fatto che System.Object sia la madre di tutti è assicurato al più basso livello possibile. Questo vuol dire che, anche se un compilatore volesse definire una classe al di fuori della gerarchia di classi che ha come root SystemObject, non potrebbe.
Il testo originale delle specifiche:
"If no type is specified, ilasm will add an extend clause to make the type inherit from System.Object."
Sapete perché il seguente codice C# non da errori a runtime mentre il corrispondente VB .NET sì (System.OverflowException)?
C#
VB .NET
int a = int.MaxValue;int b = a + 1;
Dim a As Integer = Integer.MaxValueDim b As Integer = a + 1
Semplicemente perché il compilatore C# traduce la somma nell'istruzione IL add, mentre il compilatore VB .NET la traduce nell'istruzione add.ovf (come add ma con la verifica di overflow). Più performante, ovviamente, la variante C#.
Spiegazione letta nel libro di Robinson (p. 21).
Spesso si confondono:
ILAsm = IL assembly (IL source code)
ilasm(.exe) = IL assembler
Questo è dovuto alla doppia rappresentazione di IL, sorgente e binaria, tra cui esiste una corrispondenza 1:1. A ogni istruzione di ILAsm corrisponde un opcode di IL che occupa 1 o al massimo 2 byte, direttamente parte dell'assembly. Quindi, quando parliamo di IL, sottintendiamo codice IL.
Questa doppia rappresentazione di IL è anche il motivo per cui ilasm non è un compilatore: solo sostituisce le mnemoniche di IL con i corrispondenti opcode.
Lo spiega bene Simon Robinson nel suo libro, "Expert .NET 1.1 Programming" (p. 2-3).
using System;namespace Quiz.System{ class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
namespace Quiz.System{ using System; class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
Chi votereste? Destra o sinistra? E perché?
L'ultimo mese dell'anno, la bloggorroicità ha colpito duro la nostra comunità già provata dal linkaholismo più sfrenato :-) Visti i buoni segnali di penitenza (la sindrome d'inizio anno?) provo a suggerire due rimedi a queste malattie:
il primo, per la cura della bloggorroicità, lo conoscete già tutti: aprire un blog personale su Blogger.com o su qualunque altro host che vi piace di più e linkarlo nel vostro blog su UGI. Così, i vostri veri very funny fan non perderanno niente, mentre al resto dei lettori arriveranno gli altri post in maniera più coerente. Io personalmente, di alcune comunità (compresa la nostra)...