Gdzie jest naprawdę plik kompilatora

0

Witam,

Mam problem:

Podczas kompilacji probnego programu C# w Output Window pojawia się (między innymi) taki wpis:

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 .....

Jednak plik Csc.exe jest tylko sprawdzany na warunek istnienia, a nie jest wcale wykonywany. [???]
Dla próby podstawiłem zamiast niego dowolny plik (np tekstowy) o długości kilku bajtów zmieniłem mu nazwę na Csc.exe,
przeładowałem VS i dokonałem próbnej kompilacji. Przeszła bez błędów !

Jeśli plik ten całkowicie usunąłem to pojawił się błąd:

c:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.CSharp.targets(135,9): error MSB6004: The specified task executable location "C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe" is invalid.
Done building project "Proba.csproj" -- FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

Czy ktoś może wie jaki plik jest używany do kompilacji C# ?

0

Teoretycznie ta wiedza jest ci w niczym nie potrzebna. Kompiluje się plikiem csc.exe. I jeżeli wpiszesz do konsoli csc.exe nazwa_pliku.cs to program ci się skompiluje. Możliwe jest, że kompilator znajduje się gdzie indziej (a właściwie znajduje się w folderze wskazywanym przez zmienną PATH) i jeżeli zamienisz plik kompilatora w Framework to nic ci nie da, bo i tak jest kompilowany np. z C:\Windows\System. Podczas kompilacji visual studio(czy czego tam używasz) sprawdza czy wszystko czego potrzebuje jest zainstalowane i gotowe do użycia.

Więcej na temat csc.exe:
http://msdn.microsoft.com/en-us/library/78f4aasd.aspx

I nie zadawaj pytań (o których wiedza jest ci zupełnie niepotrzebna) na które masz odpowiedź w pierwszym lepszym linku od google.

0

I nie zadawaj pytań (o których wiedza jest ci zupełnie niepotrzebna) na które masz odpowiedź w pierwszym lepszym linku od google.

1.Czy możesz mi powiedzieć skąd wiesz do czego ta wiedza jest mi potrzebna, a bardziej precyzyjnie „zupełnie nie potrzebna” ?

2.Z zasady nie zadaję na forum pytań „gdzie na klawiaturze jest Enter”. Link który podałeś nie wyjaśnia sprawy, a jedynie podaje informacje w zasadzie znane lub takie których się łatwo domyśleć (np. PATH)

3.Gdybyś zechciał się wczytać dokładniej w tekst pytania, może zwróciłbyś uwagę na fakt że znalazłem plik kompilatora który teoretycznie jest wykorzystywany do kompilacji w środowisku VS2008, jednak jak już pisałem w rzeczywistości nie on jest używany do kompilacji.

4.Może byłbyś łaskaw bardziej precyzyjnie powiedzieć co jest specjalnego w katalogu C:\Windows\System\ (z punktu widzenia kompilacji C#).

5.To że za pomocą pliku csc.exe (plus cscompui.dll) można z linii komend kompilować to wielokrotnie sprawdziłem przed „zaśmiecaniem forum głupimi pytaniami”.

6.Jeśli moje pytanie było tak naiwne to pewnie bez większych problemów możesz odpowiedzieć w prosty i zrozumiały sposób mniej więcej tak: „Plik kompilatora C# wykorzystywany przez środowisko IDE VS2008 to C:\Windows...\compcs.exe. Ten plik to rzeczywisty kompilator”.

0

Sprobuj wykonac ponowna "kompilacje bez bledow" wlaczajac opcje Rebuild... Zbudowanie zbudowanego solution nie zrobi tego samego powtornie - jesli nie bylo zmian, to IDE nie bedzie kompilowac.

0

MSBuild.exe też odpada. Myślę, że IDE kompiluje kod dynamicznie z wykorzystaniem na przykład:
http://msdn.microsoft.com/en-us/library/system.codedom.compiler.aspx
Które biblioteki .dll za to odpowiadają to już nie wiem.

0

Być może IDE ma w sobie wbudowanego kompilatora, a przestrzenie nazw CSharp są jakby nakładką na kompilator (robią to samo). Warto zauważyć, że każda wersja frameworka ma swoje kompilatory. U siebie znalazłem ten plik w następujących lokalizacjach: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727, C:\WINDOWS\Microsoft.NET\Framework\v3.5, C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319 bo takie jego wersje mam. Ścieżka może też zależeć od właściwości projektu dla jakiej wersji frameworka jest projekt kompilowany (target framework). Gdy chcesz budować aplikację, które podczas pracy tworzą pakiety (np. aplikacje rozszerzalne, ściągają źródła i je kompilują) za pomocą przestrzeni System.CodeDom.Compiler.

String[] sourceName = {@"c:\t\program.cs",@"c:\t\PobierzWektor.cs",@"C:\t\PobierzWektor.Designer.cs"};
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
if (provider != null)
            {

                // Format the executable file name.
                // Build the output assembly path using the current directory
                // and <source>_cs.exe or <source>_vb.exe.

                String exeName = @"c:\t\pg.exe";

                CompilerParameters cp = new CompilerParameters();
                //Ustawienie podstawowych referencji
                cp.ReferencedAssemblies.Add("System.dll");
                cp.ReferencedAssemblies.Add("System.core.dll");
                cp.ReferencedAssemblies.Add("System.Data.dll");
                cp.ReferencedAssemblies.Add("System.Drawing.dll");
                cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
                // Generate an executable instead of 
                // a class library.
                cp.GenerateExecutable = true;
                
                cp.EmbeddedResources.Add(@"c:\t\PobierzWektor.resx");
                // Specify the assembly file name to generate.
                cp.OutputAssembly = exeName;

                // Save the assembly as a physical file.
                cp.GenerateInMemory = false;

                // Set whether to treat all warnings as errors.
                cp.TreatWarningsAsErrors = false;
                cp.CompilerOptions = "/target:winexe";
                // Invoke compilation of the source file.
                CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceName);
                string kom;
                if (cr.Errors.Count > 0)
                {
                    // Display compilation errors.
                    kom = string.Format("Wsytąpiły błędy podczas kompilacji pliku: {0} w {1}",
                        sourceName, cr.PathToAssembly);
                    kom += System.Environment.NewLine;
                    foreach (CompilerError ce in cr.Errors)
                    {
                        Console.WriteLine("  {0}", ce.ToString());
                        Console.WriteLine();
                        kom += string.Format("  {0}", ce.ToString());
                    }
                    MessageBox.Show(kom);
                }
                else
                {
                    // Display a successful compilation message.
                    kom = string.Format("Source {0} built into {1} successfully.",
                        sourceName, cr.PathToAssembly);
                    MessageBox.Show(kom);
                }

                // Return the results of the compilation.
                if (cr.Errors.Count > 0)
                {
                    compileOk = false;
                }
                else
                {
                    compileOk = true;
                }
            }
 
0

Dziękuję kolegom za zainteresowanie i pomoc.

Po analizie podpowiedzi też dochodzę do wniosku że środowisko IDE kompiluje dynamicznie (choć nadal nie wiem po co w takim razie sprawdza istnienie kompilatora csc.exe).

Może jednak zdradzę po co mi ta wiedza była potrzebna. Otóż powód jest trochę wstydliwy i pewnie zostanę wyśmiany przez wielu czytających [wstyd]

Programuję w C ( potem w C++ a teraz przechodzę na C#) od 1986 roku to jest ponad 20 lat. Do programowania w C przeszedłem po kilku latach kodowania w PL/I, a w tym  języku istniało słowo kluczowe THEN np
  IF ( ....) 
   THEN ....; 
   ELSE ....;

Polubiłem tę symetrię zapisu i w języku C i C++ stosowałem następujący trik:

#define then      /* pusta definicja w pliku nagłówkowym */
     ......
if (...) 
 then return 3;         // Prekompilator zamienia
 else return 4;         // then na white_space   
     .....

Trzymałem się tego przez ponad dwadzieścia lat, a teraz ze względu na ograniczenia preprocesora w C# muszę z tego zrezygnować :-( .

Myślałem o tym aby w potok kompilacji wtrącić niewielki program który nadpisywałby cztery litery słowa then czterema spacjami. Oczywiście musiałby to robić na kopii pliku źródłowego np. proba.cs -> proba_.cs. Taką zmodyfikowaną postać pliku wraz ze zmiana nazwy w parametrach przekazywać chciałem do oryginalnego kompilatora czyli csc.exe.

Aby wpiąć się we własnym środowisku VS chciałem zmienić nazwę oryginału z csc.exe na np. cscorg.exe zaś własną nakładkę o nazwie csc.exe wgrać do katalogu gdzie jest oryginał.

Niestety w przypadku dynamicznej kompilacji stosowanej przez IDE nie wiem jak dokonać podobnej ‘podmianki’.

Jeśli ktoś ma jakiś pomysł to będę wdzięczny za pomoc w tym temacie.

0

To dość dziwny pomysł. O wiele lepiej będzie zmienić swoje przyzwyczajenie. Z resztą pewnie wiesz dlaczego.

Użyj build events. W opcjach projektu masz. Napisz sobie program albo użyj czegoś w stylu awk do zrobienia kopii wszystkich plików .cs, zamiany stałej w oryginalnych i w post-build przywrócenie oryginałów.

Nie wiem tylko czy jakaś magiczna wbudowana obsługa błędów w Visual Studio przed kompilacją w ogóle pozwoli na takie coś.

0

Zmiana przyzwyczajeń w moim wieku nie jest taka prosta. Nadal piszę w C++ i to dużo więcej niż w C#, dlatego też wolałbym pozostać przy ulubionym sposobie formatowania kodu źródłowego. Oczywiście jeśli nie uda mi się jakoś rozwiązać tego problemu to nie pozostanie mi nic innego.

Jeśli chodzi o użycie BuildEvents to pociąga to za sobą ręczne dopisywanie event’ów w każdym nowym projekcie co jest trochę uciążliwe. Wolałbym rozwiązanie typu ‘raz się narób by potem mieć święty spokój’.

0

Chcesz mieć śliczny i czytelny kod - przejdź na Brainfuck. :>

A tak na serio - trzeba iść z duchem czasu. Ja osobiście preferuję VB.NET (właśnie ze względu na czytelną i intuicyjną składnię -> http://www.harding.edu/fmccown/vbnet_csharp_comparison.html), ale gdybym musiał pisać w czymś innym np. żeby pracować w zespole, który używa C# - nie byłby to zbyt wielki problem.

Weź pod uwagę, że gdy ktoś popatrzy na Twój kod (napisany w zmodyfikowanym C#) - nie będzie umiał go rozczytać. ;)

0
Anthony napisał(a)

Weź pod uwagę, że gdy ktoś popatrzy na Twój kod (napisany w zmodyfikowanym C#) - nie będzie umiał go rozczytać. ;)

Zapomniałem dodać że zmodyfikowany kod źródłowy oglądam sam lub osoby z zespołu też przyzwyczajone do tej 'dzikiej modyfikacji. Na zewnątrz f-my jeśli trzeba pliki są udostępniane po przejciu przez ten sam program który usuwa lub nadpisuje spacjami słowo then.

Jak przewidywałem zostanę teraz zasypany propozycjami 'odpuszczenia sobie i powrotu do szeregu' :> a ja tylko pokornie proszę o propozycję jak rozwiązać to może dziwne zadanie.

0
Wlodek55 napisał(a)

Trzymałem się tego przez ponad dwadzieścia lat, a teraz ze względu na ograniczenia preprocesora w C# muszę z tego zrezygnować :-( .

Bardzo mocny zarzut. Brak #define w C# jest akurat jedną z wielu jego zalet polegających na oczyszczeniu składni z błędogennych, śmieciowych i trudnych w debugowaniu instrukcji.
Nazywasz coś ograniczeniem, tylko dlatego, że jest niezgodne z jakimiś tam Twoimi przyzwyczajeniami.
Ty chcesz zmodyfikować składnię języka. To tak jakby zmieniać pod siebie zasady ruchu drogowego...
Popełniłeś błąd upodabniając na siłę składnię języka sprzed trzydziestu lat do języka sprzed lat pięćdziesięciu. A teraz chcesz do niej dopasować nowoczesny język i dziwisz się, że się nie daje.
Nie wiem, czy zauważyłeś, ale przed barami w miastach nie ma już poideł dla koni. Po prostu świat się rozwija.

Jeśli chodzi o użycie BuildEvents to pociąga to za sobą ręczne dopisywanie event’ów w każdym nowym projekcie co jest trochę uciążliwe. Wolałbym rozwiązanie typu ‘raz się narób by potem mieć święty spokój’.

To zrób szablon projektu ze skonfigurowanymi eventami i go używaj, może tak da radę.

Anthony napisał(a)

właśnie ze względu na czytelną i intuicyjną składnię

Generalnie rozwlekła składnia nie może być ani czytelna ani intuicyjna. Może być co najwyżej zrozumiała dla osoby znającej angielski i nie chcącej się nauczyć języka o oszczędniejszej składni.

0

'Ograniczeniem' procesora nazywałem w skrócie brak możliwości definicja makra.

somekind napisał(a)

Brak #define w C# jest akurat jedną z wielu jego zalet polegających na oczyszczeniu składni z błędogennych, śmieciowych i trudnych w debugowaniu instrukcji.

Problem w tym że 'móc' wcale nie oznacza 'musieć'. To że preprocesor w C++ daje możliwości pisania naprawdę dziwnych konstrukcji nie oznacza że każdy programista C++ musi takie konstrukcje tworzyć.

Co do modyfikacji składni języka to trochę przesadzasz. Nie wymagam od kompilatora zgłaszania błędu przy braku 'then' a jedynie by ignorował jego istnienie.

0
Wlodek55 napisał(a)

Problem w tym że 'móc' wcale nie oznacza 'musieć'. To że preprocesor w C++ daje możliwości pisania naprawdę dziwnych konstrukcji nie oznacza że każdy programista C++ musi takie konstrukcje tworzyć.

Problem w tym, że skoro da się coś zepsuć w ten sposób to prędzej czy później się zepsuje. Prawa Murphy'ego działają zawsze. ;)
I nie chodzi mi o dziwne konstrukcje, tylko o to, że jeśli ktoś gdzieś przypadkiem swoim define nadpisze coś w jednym z tysięcy plików w projekcie, to później ciężko taki błąd znaleźć.
Im mniej możliwości popełnienia błędu, tym łatwiejsza praca. Dlatego np. w C# nie ma fall-through switch, a w warunku if może być jedynie wartość logiczna.

Co do modyfikacji składni języka to trochę przesadzasz. Nie wymagam od kompilatora zgłaszania błędu przy braku 'then' a jedynie by ignorował jego istnienie.

Wymagasz od kompilatora, aby zignorował nieznane mu wyrażenie użyte przez Ciebie w nieodpowiednim kontekście. Moim zdaniem to modyfikacja składni.

0

Somekind - wydaje mi się że koniecznie chcesz wejść w dyskusję o wyższości jednego języka nad drugim. Ja nie chcę. Jeśli czujesz, że swym nieopatrznym stwierdzeniem o ‘ograniczeniach preprocesora C#’ naraziłem na szwank dobre imię języka C# to biję się w piersi i proszę o wybaczenie. [wstyd]

Wracając jednak do praw Murphy'ego i przypadkowym nadpisaniu czegoś w jednym z tysięcy plików to powiem Ci że nie przypominam sobie abym kiedykolwiek miał z tym problem, choć popełniłem w swej karierze programisty wiele błędów. Po prostu wykorzystywałem możliwości preprocersora z umiarem, a w C++ używam go jeszcze mniej.

Widziałem wiele przypadków popełnienia błędów w regularnym kodzie (nie w makrach preprocesora) które przepuściłby każdy kompilator (choćby przez nieprzemyślany dobór nazw zmiennych o podobnej pisowni). System mógł pracować przez wiele lat bez ujawnienia się tego bug’a. Po prostu jeśli coś jest pisane niechlujnie to wynik jest do przewidzenia. Niewiele tu pomoże język czy kompilator bo przecież kod programu jest w 100% poprawny składniowo, a że niepoprawny semantycznie to inna sprawa. Ograniczanie możliwości języka tylko dlatego żeby ktoś sobie ‘nie zrobił krzywdy’ nie jest dla mnie zbyt przekonujące. Przez analogię producent noży powinien wypuszczać na rynek tylko tępe produkty z zaokrąglonym końcem 'oby tylko klient się nie skaleczył'. Moim zdaniem w sprzedaży powinny być noże ostre i tępe, a klient powinien mieć po prostu możliwość wyboru.

Jeśli chodzi o do modyfikację składni to chyba mnie nie rozumiesz. Nie pytałem jak zmusić kompilator do bezwzględnego wymagania w kodzie then po każdym if’ie. Pytałem jak spowodować aby then nie powodowało błędów ani nawet ostrzeżeń przy kompilacji i jak możesz wyżej przeczytać sugerowałem rozwiązanie usuwające przed wejściem do kompilatora to ‘dzikie słowo kluczowe’. W takim przypadku kod źródłowy widziany przez kompilator jest całkiem poprawny składniowo (zgodnie ze standardem języka), czyli z punktu widzenia kompilatora nie ma tu zjawiska modyfikacji składni języka. Gdybym próbował modyfikować kod parsera (tylko skąd wziąć źródła ?) to wtedy zgoda – to byłaby modyfikacja składni języka, gdyż taki ‘zmieniony’ kompilator krzyczałby przy każdym braku then.
Jeśli jednak zajrzeć do składni w notacji EBNF to można zauważysz, że istnieje coś takiego jak ‘wystąpienia opcjonalne’. Tak zmodyfikowany parser mógłby zaspokoić Twoje i moje ‘gusta’.
Co do nadmiernie rozdmuchanej składni to moim zdaniem jest to już naprawdę kwestia gustu (czyli poza merytoryczną dyskusją). Dla mnie stosowanie then oprócz wartości wizualnej ma jeszcze tę zaletę że zmniejsza ilość popełnianych błędów. Nie chodzi mi o większą zgodność z językiem angielskim, ani o fakt zgodności z jednym z archaicznych języków. Tak na marginesie pragnę tylko dodać że trik z ‘then’ wymyślił jakiś znany informatyk (chyba z IBM) i też zalecał jego stosowanie z kilku względów (niestety już nie pamiętam kto to był).
Jednak „ludziom tak trudno dogodzić’ – wielokrotnie słyszałem zarzuty pod adresem języka C++ że jest zbyt zwięzły np. x=(z<3)?++a:--b;

Ale to moja opinie i prawdopodobnie masz tu całkiem odwrotne zdanie. No cóż – na szczęście żyjemy w demokratycznym kraju. :-D

Na koniec – wyciągając rękę na zgodę – ja nie chcę nikomu narzucać swojego ulubionego sposobu formatowania kodu. Ja po prostu chciałbym mieć taką możliwość w moim prywatnym komputerze nie publikując nigdzie na zewnątrz takiego then’owego kodu. Zresztą byłoby to nie logiczne, gdyż taki ‘dziwny kod’ nie kompilowałby się u nikogo poza moim środowiskiem pracy (chyba że dystrybuowałbym wraz z nim zmodyfikowany kompilator czy jakąś tam nakładkę do niego).

0
Wlodek55 napisał(a)

Somekind - wydaje mi się że koniecznie chcesz wejść w dyskusję o wyższości jednego języka nad drugim.

Jeśli chodzi o C++ to ciężko byłoby mówić o jakiejkolwiek wyższości nad czymkolwiek pod względem składni.

Ograniczanie możliwości języka tylko dlatego żeby ktoś sobie ‘nie zrobił krzywdy’ nie jest dla mnie zbyt przekonujące.

Po prostu te "ograniczenia" w C# pozwalają na uniknięcie pewnych prostych błędów wynikających z roztargnienia czy nieuwagi, które w C++ przechodzą. Wiadomo, że błędny kod można napisać w każdym języku, po prostu w niektórych o to trudniej.
Nikt sobie krzywdy nie zrobi, tu o czas pracy chodzi. A czas to pieniądz.

I "ograniczanie" jest chyba złym słowem w tym przypadku. C# to nie jest nowa wersja C++ bez niektórych jego możliwości. To zupełnie inny język i nie można oczekiwać, że będzie się zachowywał jak jakiś inny język. Równie dobrze można powiedzieć, że jest ograniczony względem Pascala, bo nie ma begin i end - to bez sensu.

Moim zdaniem w sprzedaży powinny być noże ostre i tępe, a klient powinien mieć po prostu możliwość wyboru.

No i masz możliwość. Nie musisz chyba pisać w C#. :)

Jeśli chodzi o do modyfikację składni to chyba mnie nie rozumiesz.

Ja rozumiem co chcesz zrobić.
IMHO składnia istnieje na poziomie kodu źródłowego. A Twój plik z "then" nie będzie już plikiem w języku C#, bo nie będzie się kompilował standardowym kompilatorem tego języka. Będzie miał zmienioną składnię. A przeparsowanie go i wysłanie do kompilatora już bez tego słowa, to inna rzecz.

Co do nadmiernie rozdmuchanej składni to moim zdaniem jest to już naprawdę kwestia gustu (czyli poza merytoryczną dyskusją). Dla mnie stosowanie then oprócz wartości wizualnej ma jeszcze tę zaletę że zmniejsza ilość popełnianych błędów.

Rozumiem Twoje przyzwyczajenie. :) Ale uwaga o rozdmuchaniu składni była o VB, nie o "then". ;)

Ja po prostu chciałbym mieć taką możliwość w moim prywatnym komputerze nie publikując nigdzie na zewnątrz takiego then’owego kodu.

Więc albo zrób to, co zaproponował Rev.pl, albo napisz swój preprocesor, który obsłuży Twoje #define, a potem wyśle kod do csc.exe. I kompiluj wywołując z wiersza poleceń, a nie z Visual Studio. Bo i tak nie ma sensu używać VS w pliku z niepoprawnym składniowo kodzie z "then", gdyż chociażby Intellisense zwariuje.
A ja postaram się jeszcze coś przez weekend wykombinować, jak wpadnę na jakiś pomysł, to dam znać. :)

0
somekind napisał(a)

(...) albo napisz swój preprocesor, który obsłuży Twoje #define, a potem wyśle kod do csc.exe. (...)

W jakim celu pisać nowy pre-procesor jak można przepuścić kod przez ten od C++?
http://connect.microsoft.com/VisualStudio/feedback/details/90887/indroduce-the-c-pre-processor-macro-abaility-into-c

0

Popełniłeś błąd upodabniając na siłę składnię języka sprzed trzydziestu lat do języka sprzed lat pięćdziesięciu.

Chciałeś powiedzieć języka sprzed lat 38 do języka sprzed lat 40. Argument czasowy nieistotny ;-)

Google pod tematem C# macro, C# preprocessor wynajduje kilka prób podejścia do tematu.

0
somekind napisał(a)

Więc albo zrób to, co zaproponował Rev.pl, albo napisz swój preprocesor, który obsłuży Twoje #define, a potem wyśle kod do csc.exe. I kompiluj wywołując z wiersza poleceń, a nie z Visual Studio. Bo i tak nie ma sensu używać VS w pliku z niepoprawnym składniowo kodzie z "then", gdyż chociażby Intellisense zwariuje.

Mea culpa – nazwa tego tematu powinna brzmieć:
„Gdzie jest kompilator używany przez IDE VS2008 do kompilacji programów pisanych w języku C#” –ale tekst jest stanowczo za długi !
Możliwość kompilacji z wiersza poleceń to oczywistość o której nawet nie wspominałem (chyba że w pierwszym wpisie do tematu). Ten sposób pracy jest jak dla mnie na tyle nienaturalny że pozwoliłem sobie na poruszenie tego tematu. Ponadto w C++ Intellisense nie głupieje aż tak bardzo, aby stanowiło to dla mnie problem (tak przy okazji - poza środowiskiem VS Intellisense w ogóle nie istnieje, więc wolę mieć trochę ogłupiałego niż nic).

somekind napisał(a)

Więc albo zrób to, co zaproponował Rev.pl, albo napisz swój preprocesor, który obsłuży Twoje #define, a potem wyśle kod do csc.exe.

No właśnie problem w tym że csc.exe nie jest używany do kompilacji z IDE.

Wlodek55 napisał(a)

Moim zdaniem w sprzedaży powinny być noże ostre i tępe, a klient powinien mieć po prostu możliwość wyboru.

somekind napisał(a)

No i masz możliwość. Nie musisz chyba pisać w C#.

Tu niestety nie masz racji – jestem zmuszony przez klienta który wymaga (np. ze względu na kompatybilność z istniejącym kodem) na pisanie w C#. Jak wiesz nie zawsze możesz sobie wybrać język w którym masz napisać program, zwłaszcza gdy jest to część większego systemu.

somekind napisał(a)

I "ograniczanie" jest chyba złym słowem w tym przypadku. C# to nie jest nowa wersja C++ bez niektórych jego możliwości. To zupełnie inny język i nie można oczekiwać, że będzie się zachowywał jak jakiś inny język. Równie dobrze można powiedzieć, że jest ograniczony względem Pascala, bo nie ma begin i end - to bez sensu.

Zgadzam się – użycie przeze mnie słowa "ograniczenie" (ze względu na pejoratywne znaczenie w tym kontekście) nie było zbyt fortunne. Tak mówiąc ogólnie ja nie krytykuję tu języka C# który jak większość wytworów człowieka ma zalety ale też ma wady. Jest kilka rzeczy (w porównaniu do C++ ) które są po prostu piękne, ale jest kilka które mnie się nie za bardzo podobają (o tych nie chcę pisać by nie wywołać burzy).

Anthony napisał(a)

W jakim celu pisać nowy pre-procesor jak można przepuścić kod przez ten od C++?

Otóż w takim aby uniemożliwić ‘niebezpieczne’ konstrukcje które przepuściłby pełny preprocesor języka C++ (somekind tu chyba mnie poprzesz ? :-) )

1

Tu niestety nie masz racji – jestem zmuszony przez klienta który wymaga (np. ze względu na kompatybilność z istniejącym kodem) na pisanie w C#. Jak wiesz nie zawsze możesz sobie wybrać język w którym masz napisać program, zwłaszcza gdy jest to część większego systemu.

To może napisz kod w VB.NET albo czystym zarządzanym C++/CLI (nie jestem pewien czy istnieje "czysta wersja") i przeleć jakimś reflektorem który ci zamieni kod na składniowo C#? Chyba że naprawdę wolisz pisać w C#.

0

czystym zarządzanym C++/CLI (nie jestem pewien czy istnieje "czysta wersja")

tak, istnieje, parametr kompilatora /clr:pure

 (zezwala na unsafe) lub <code noframe>/clr:safe

(bez unsafe)

0
Wlodek55 napisał(a)

Ponadto w C++ Intellisense nie głupieje aż tak bardzo, aby stanowiło to dla mnie problem (tak przy okazji - poza środowiskiem VS Intellisense w ogóle nie istnieje, więc wolę mieć trochę ogłupiałego niż nic).

Intellisense nie działa w niepoprawnym kodzie. Po pierwszym Twoim "then" nie podpowie Ci już nic sensownego. Nie będziesz miał Intellisense.

No właśnie problem w tym że csc.exe nie jest używany do kompilacji z IDE.

Dlatego zaproponowałem olanie IDE. ;) No, ale jeśli to Ci nie pasuje, to najsensowniejsza jest chyba propozycja MSM.

Jak wiesz nie zawsze możesz sobie wybrać język w którym masz napisać program, zwłaszcza gdy jest to część większego systemu.

Cóż - ja akurat mogę. :)

Otóż w takim aby uniemożliwić ‘niebezpieczne’ konstrukcje które przepuściłby pełny preprocesor języka C++ (somekind tu chyba mnie poprzesz ? :-) )

Jasne. :)

Azarien napisał(a)

Popełniłeś błąd upodabniając na siłę składnię języka sprzed trzydziestu lat do języka sprzed lat pięćdziesięciu.

Chciałeś powiedzieć języka sprzed lat 38 do języka sprzed lat 40. Argument czasowy nieistotny ;-)

Ja liczyłem PL/I jako początek lat 60tych i C++ jako początek 80tych, ale zawsze mogę się mylić. Nie było mnie wtedy. ;)

0
MSM napisał(a)
Wlodek55 napisał(a)

Tu niestety nie masz racji – jestem zmuszony przez klienta który wymaga (np. ze względu na kompatybilność z istniejącym kodem) na pisanie w C#. Jak wiesz nie zawsze możesz sobie wybrać język w którym masz napisać program, zwłaszcza gdy jest to część większego systemu.

To może napisz kod w VB.NET albo czystym zarządzanym C++/CLI (nie jestem pewien czy istnieje "czysta wersja") i przeleć jakimś reflektorem który ci zamieni kod na składniowo C#? Chyba że naprawdę wolisz pisać w C#.

Prawdę mówiąc jeśli mam wybierać między zarządzanym C++ a C# to już wolę C#. Jeśli już musi mi rządzić się w pamięci operacyjnej GC, to wolę o wiele bardziej czysty język jakim jest C#. Moim skromnym zdaniem C++ z dodatkami typu String^ czy gcnew to już naprawdę zaśmiecona konstrukcja i trudno go obronić przed zarzutem że to ‘trudny język” (ja bym raczej powiedział że bałaganiarski).

Ponadto czasami zleceniodawca chcąc mieć porządek w kodzie systemu nie godzi się na dwa języki np. C# i managed C++ co jak dla mnie jest w pełni zrozumiałe.

somekind napisał(a)

Intellisense nie działa w niepoprawnym kodzie. Po pierwszym Twoim "then" nie podpowie Ci już nic sensownego. Nie będziesz miał Intellisense.

To prawda ale tylko do pierwszego ‘;’ – potem ogłupienie mu przechodzi.

------------------------------------ To jest gruba kreska --------------------------------------

Panowie spróbujmy może podejść inaczej do tematu, tak aby nie dyskutować na temat samego języka C# (bo przyjdzie moderator i wygoni wszystkich z lasu :-D ).
Dlatego stawiam pytanie następujące:

Czy ktoś wie jak w IDE VS2008 wprowadzić do pipeline’u kompilatora dodatkowy program modyfikujący plik źródłowy tuż przed wejściem do kompilatora ? (może już bez wchodzenia w szczegóły typu "po co mi to").

1

Czy ktoś wie jak w IDE VS2008 wprowadzić do pipeline’u kompilatora dodatkowy program modyfikujący plik
źródłowy tuż przed wejściem do kompilatora ? (może już bez wchodzenia w szczegóły typu "po co mi to").

W zakładce Properties->DebugEvents możesz sobie ustawić dowolne polecenia do wykonania przez cmd przed (Pre-build) i po (Past-build) kompilacji, ale to będzie prawdopodobnie wymagało nieco zabawy (żeby ci plików z kodem "ulepszonym" nie nadpisało "transformowanym" - kopiowanie do plików tymczasowych i z powrotem) i nie wiem czy warto. Może ktoś tutaj zna lepszy sposób.

0

I wszystko jasne !!!

Problem leży w bałaganiarstwie f-my MicroSoft :> . VS2008 i chyba VS2005 posiada kompilator wewnętrzny tzw. „in-process compiler” i dodatkowo kompilator Csc.exe. Ten wewnętrzny działa trochę szybciej na małych projektach, ale ponoć nie radzi sobie z bardziej zaawansowanymi projektami czy składnią LINQ. W zasadzie kompilując ze środowiska IDE VS używany jest in-process compiler choć w oknie Output oszukańczo pojawia się napis że wywoływany jest kompilator Csc.exe co nie jest prawdą !!!

C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 ....
Co ciekawe kod CIL produkowany przez te kompilatory trochę się różni (czasami nawet bardzo). W zasadzie dużo lepszy kod produkuje Csc.exe.

Aby się dowiedzieć który kompilator jest używany należy ustawić:

Tools->Options... Project and Solutions-> Build and Run->MSBuild project build output verbosity – Normal
Przy takich ustawieniach w oknie Output otrzymamy (przykładowo):

dla projektu A:

Target CoreCompile:
    C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 ....

Compile complete -- 0 errors, 0 warnings
Target CopyFilesToOutputDirectory:

dla projektu B:

Target CoreCompile:
    C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 .....
Target CopyFilesToOutputDirectory:

Projekt A jest kompilowany za pomocą „in-process compiler” , zaś projekt B za pomocą Csc.exe ( in-process wyświetla licznik błędów i ostrzeżeń, zaś Csc.exe nie).

Aby wymusić kompilacje za pomocą Csc.exe należy:

  1. Do pliku projektu dodać linie
  <PropertyGroup>
    <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  </PropertyGroup>
  1. W pliku Microsoft.CSharp.targets (w katalogu Framework 3.5) zamienić true na false.
   <PropertyGroup>
        <!-- Provide a facility to override UseHostCompilerIfAvailable-->
        <UseHostCompilerIfAvailable Condition=" '$(UseHostCompilerIfAvailable)' == ''">false</UseHostCompilerIfAvailable>
    </PropertyGroup>

Pierwszy sposób ustawia działanie indywidualnie dla projektu, drugi działa jako wzorzec przy kreacji nowego projektu.

Tak więc problem postawiony w temacie został w zasadzie rozwiązany. :-D

Dziękuję wszystkim za pomoc i cenne uwagi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1