"sinnlose" defines?



  • z.T. werden leere Makros auch als Annotationen für static code analysis Tools verwendet.
    Ein Beispiel aus dem Windows SDK:

    WINBASEAPI
    DWORD
    WINAPI
    GetFullPathNameW(
        __in            LPCWSTR lpFileName,
        __in            DWORD nBufferLength,
        __out_ecount_part_opt(nBufferLength, return + 1) LPWSTR lpBuffer,
        __deref_opt_out LPWSTR *lpFilePart
        );
    

    WINBASEAPI: __declspec(dllimport)
    WINAPI: __stdcall
    __in, __out_ecount_part_opt() und __deref_opt_out: Annotationen für MS' static code analysis Tools.

    Wobei das Beispiel nicht perfekt ist, denn wenn man mit MSVC compiliert, dann sind diese Makros gar nicht leer. Sie könnten aber genau so gut leer sein 😉



  • Ok, danke für die Aufklärung 👍

    Manchmal kommts mir halt nur echt so vor als würden die std (oder auch die WinApi) Entwickler einfach absichtlich häßlichen Code schreiben den keiner entziffern kann...


  • Mod

    happystudent schrieb:

    Manchmal kommts mir halt nur echt so vor als würden die std (oder auch die WinApi) Entwickler einfach absichtlich häßlichen Code schreiben den keiner entziffern kann...

    Ganz im Gegenteil, die bemühen sich den Code lesbar zu halten. Schließlich müssen sie ihn doch warten. Alles was Lesbarkeit vermindert ist nötig.



  • Arcoth schrieb:

    happystudent schrieb:

    Manchmal kommts mir halt nur echt so vor als würden die std (oder auch die WinApi) Entwickler einfach absichtlich häßlichen Code schreiben den keiner entziffern kann...

    Ganz im Gegenteil, die bemühen sich den Code lesbar zu halten. Schließlich müssen sie ihn doch warten. Alles was Lesbarkeit vermindert ist nötig.

    ich erinnere mich in einen Talk von Microsoft STL Entwickler, der sich STL nennt (Steven..), gehört zu haben das eine gewisse Hässlichkeit bei der Implementierung gewollt angewendet wird, um zb nicht mit Namen zu kollidieren und ähnliches.


  • Mod

    eine gewisse Hässlichkeit bei der Implementierung gewollt angewendet wird, um zb nicht mit Namen zu kollidieren und ähnliches.

    Natürlich. Es werden _Solche __identifier verwendet, die für alle Zwecke der Implementierung reserviert sind. Das ist nötig, wie du bereits erwähnt hast.



  • Arcoth schrieb:

    happystudent schrieb:

    Manchmal kommts mir halt nur echt so vor als würden die std (oder auch die WinApi) Entwickler einfach absichtlich häßlichen Code schreiben den keiner entziffern kann...

    Ganz im Gegenteil, die bemühen sich den Code lesbar zu halten. Schließlich müssen sie ihn doch warten. Alles was Lesbarkeit vermindert ist nötig.

    Das stimmt nur so halb. Zumindest bei Visual Studio sieht der Code so aus, als hätte man absichtlich das Lesen erschweren wollen. Da war vermutlich nicht das Ziel, ist aber trotzdem das Ergebnis. Die geschweiften Klammern fehlen, wo es syntaktisch erlaubt ist und sind ansonsten falsch eingerückt, was das Nachvollziehen von Blöcken sehr schwer macht. Redundante Kommentare lenken vom Code ab. Es fehlen Klammern, wo man überlicherweise welche zur Verdeutlichung setzt (Zeile 8), aber an anderen Stellen wurden unnötige Klammern hinzugefügt (Zeilen 28 und 31).

    Aus VS 2012 <istream> :

    bool __CLR_OR_THIS_CALL _Ipfx(bool _Noskip = false)
    		{	// test stream state and skip whitespace as needed
    		if (this->good())
    			{	// state okay, flush tied stream and skip whitespace
    			if (_Myios::tie() != 0)
    				_Myios::tie()->flush();
    
    			if (!_Noskip && this->flags() & ios_base::skipws)
    				{	// skip whitespace
    				const _Ctype& _Ctype_fac = _USE(this->getloc(), _Ctype);
    
    				_TRY_IO_BEGIN
    				int_type _Meta = _Myios::rdbuf()->sgetc();
    
    				for (; ; _Meta = _Myios::rdbuf()->snextc())
    					if (_Traits::eq_int_type(_Traits::eof(), _Meta))
    						{	// end of file, quit
    						_Myios::setstate(ios_base::eofbit);
    						break;
    						}
    					else if (!_Ctype_fac.is(_Ctype::space,
    						_Traits::to_char_type(_Meta)))
    						break;	// not whitespace, quit
    				_CATCH_IO_END
    				}
    
    			if (this->good())
    				return (true);
    			}
    		_Myios::setstate(ios_base::failbit);
    		return (false);
    		}
    


  • Arcoth schrieb:

    Ganz im Gegenteil, die bemühen sich den Code lesbar zu halten. Schließlich müssen sie ihn doch warten. Alles was Lesbarkeit vermindert ist nötig.

    Echt? Findest du sowas hier lesbar? Also ich find das zum kotzen 😃

    Vor allem macht sowas wie #define TRY try auch überhaupt keinen Sinn, warum verwendet man nicht einfach die Schlüsselwörter dies schon gibt? So "verschmutzt" man alles nur völlig unnötig mit Macros für 0 Mehrwert...

    EDIT:
    Lol, TyRoXx ist mir da mit einem Beispiel zuvorgekommen^^

    void __CLR_OR_THIS_CALL _Copy(size_type _Newsize, size_type _Oldlen)
    		{	// copy _Oldlen elements to newly allocated buffer
    		size_type _Newres = _Newsize | _ALLOC_MASK;
    		if (max_size() < _Newres)
    			_Newres = _Newsize;	// undo roundup if too big
    		else if (_Newres / 3 < _Myres / 2
    			&& _Myres <= max_size() - _Myres / 2)
    			_Newres = _Myres + _Myres / 2;	// grow exponentially if possible
    		_Elem *_Ptr = 0;
    
    		_TRY_BEGIN
    			_Ptr = _Mybase::_Alval.allocate(_Newres + 1);
    		_CATCH_ALL
    			_Newres = _Newsize;	// allocation failed, undo roundup and retry
    			_TRY_BEGIN
    				_Ptr = _Mybase::_Alval.allocate(_Newres + 1);
    			_CATCH_ALL
    			_Tidy(true);	// failed again, discard storage and reraise
    			_RERAISE;
    			_CATCH_END
    		_CATCH_END
    
    		if (0 < _Oldlen)
    			_Traits_helper::copy_s<_Traits>(_Ptr, _Newres + 1, _Myptr(), _Oldlen);	// copy existing elements
    		_Tidy(true);
    		_Bx._Ptr = _Ptr;
    		_Myres = _Newres;
    		_Eos(_Oldlen);
    		}
    


  • happystudent schrieb:

    Echt? Findest du sowas hier lesbar? Also ich find das zum kotzen 😃

    Ich finde das auch nicht schön, ist aber auch Gewohnheitssache.
    Die kurzen Bezeichner sind z.B. ziemlich sicher absicht, einfach um Platz und dadurch auch automatisch Compilezeit zu sparen.
    Evtl. ist das (Compilezeit sparen) auch der Grund für "fehlende" {} wo es auch ohne {} erlaubt ist.

    happystudent schrieb:

    Vor allem macht sowas wie #define TRY try auch überhaupt keinen Sinn, warum verwendet man nicht einfach die Schlüsselwörter dies schon gibt? So "verschmutzt" man alles nur völlig unnötig mit Macros für 0 Mehrwert...

    Wieso bist du dir so sicher dass die Makros für try/catch überhaupt keinen Sinn haben?



  • Naja. Bei #define INT int habe ich auch keine Ahnung was das soll. Ein Sinn sehe ich da nicht direkt. Da frage ich mich warum man da sich nicht auf den Standard beruft oder einen Typ definiert wie

    #ifdef GCC32
      #define INT int
    #elif GCC64
      #define INT short
    #elif CLANG
      #define INT long
    // ...
    #endif
    

    Ich kenn auch den Trick mit defines Code zu portieren. Unter Compiler XYZ existiert HUGE Pointer. Um es für GCC zu nutzen definiert man #define HUGE.



  • hustbaer schrieb:

    Wieso bist du dir so sicher dass die Makros für try/catch überhaupt keinen Sinn haben?

    Naja... also ich sehe zumindest auch nach längerem Überlegen keinen Sinn darin.

    Das _TRY_BEGIN ist einfach nur try{ , das _CATCH_END ist } - das ist potentiell ja noch eine Einladung für Klammerfehler und was das gegenüber einem normalen try-catch bringen soll weiß ich nicht.

    Außerdem erhöht es ja auch noch die Compile- bzw. die Präprozessier-Zeit.



  • happystudent schrieb:

    hustbaer schrieb:

    Wieso bist du dir so sicher dass die Makros für try/catch überhaupt keinen Sinn haben?

    Naja... also ich sehe zumindest auch nach längerem Überlegen keinen Sinn darin.

    Das _TRY_BEGIN ist einfach nur try{ , das _CATCH_END ist } - das ist potentiell ja noch eine Einladung für Klammerfehler und was das gegenüber einem normalen try-catch bringen soll weiß ich nicht.

    Außerdem erhöht es ja auch noch die Compile- bzw. die Präprozessier-Zeit.

    Es ist eventuell möglich, dass man den Code auch vollständig ohne Exception Handling kompilieren kann, er aber dennoch bei aktivierten Exceptions diese sinnvoll behandelt. Ich wäre vorsichtig damit, so etwas pauschal als sinnlos abzutun.

    Finnegan



  • Finnegan schrieb:

    happystudent schrieb:

    hustbaer schrieb:

    Wieso bist du dir so sicher dass die Makros für try/catch überhaupt keinen Sinn haben?

    Naja... also ich sehe zumindest auch nach längerem Überlegen keinen Sinn darin.

    Das _TRY_BEGIN ist einfach nur try{ , das _CATCH_END ist } - das ist potentiell ja noch eine Einladung für Klammerfehler und was das gegenüber einem normalen try-catch bringen soll weiß ich nicht.

    Außerdem erhöht es ja auch noch die Compile- bzw. die Präprozessier-Zeit.

    Es ist eventuell möglich, dass man den Code auch vollständig ohne Exception Handling kompilieren kann, er aber dennoch bei aktivierten Exceptions diese sinnvoll behandelt. Ich wäre vorsichtig damit, so etwas pauschal als sinnlos abzutun.

    Das.
    Nur weil du jetzt keine sinnvolle Ersetzung für die Makros nicht, heißt das nicht, dass da nicht eventuell eine hinkommt.
    Das ist ja gerade der Sinn von solchen Abstraktionen, man kann später andere Dinge ersetzen.
    In diesem Fall Exceptionhandling ändern.



  • Oder noch eine Idee: vielleicht könnte man die Dinger für Unit-Tests oder Coverage-Tests verwenden.
    Frag mich jetzt nicht wie genau das aussehen könnte, aber es geht eben darum was Nathan schon geschrieben hat: Nur weil kein offensichtlicher Nutzen erkennbar ist, kann man nicht automatisch annehmen dass etwas total sinnlos ist.

    ps: Des Rätsels Lösung:

    // xstddef (MSVC 2013)
    // ...
     #else /* _HAS_EXCEPTIONS */
     #define _TRY_BEGIN	{{
     #define _CATCH(x)	} if (0) {
     #define _CATCH_ALL	} if (0) {
     #define _CATCH_END	}}
     #if defined(_DEBUG)
      #define _RAISE(x)	\
    	_invoke_watson(__STR2WSTR(#x), __FUNCTIONW__, __FILEW__, __LINE__, 0)
    
     #else /* defined(_DEBUG) */
      #define _RAISE(x)	\
    	_invoke_watson(0, 0, 0, 0, 0)
     #endif /* defined(_DEBUG) */
    // ...
    

    Also genau das was Finnegan geschrieben hat.



  • Hm Ok, bei genauer Betrachtung macht es doch irgendwo Sinn...

    Hab zwar manchmal das Gefühl das machen die absichtlich, aber gut zu sehen wenn man sich da täuscht 😉


  • Mod

    happystudent schrieb:

    Hab zwar manchmal das Gefühl das machen die absichtlich, aber gut zu sehen wenn man sich da täuscht 😉

    Natürlich ist das Absicht, aber eine andere Absicht, als du denkst.


  • Mod

    .. nicht zu vergessen dass einige Makros existieren damit man greppen kann.


Anmelden zum Antworten