Conditional compilation oddity

Discussion in 'C++' started by Norman J. Goldstein, Aug 10, 2013.

  1. The following program compiles and links.
    No warnings The output is wrong, stating:

    value= 1
    value NOT 1


    //////////////////////////////////////////////
    #include <iostream>
    using namespace std;

    static constexpr int value = 1;

    int main( int argc, char* argv[] )
    {
    cout << "value= "
    << value
    << endl;

    static_assert( value == 1, "Value_Not_1" );

    #if value == 1
    cout << "value 1" << endl;
    #else
    cout << "value NOT 1" << endl;
    #endif

    return 0;
    }// main
    /////////////////////////////////////////////////

    Why is value not used in the conditional compilation?
    (The static_assert is happy.)

    I am using
    gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)
    pn
    Linux 3.9.11-200.fc18.i686.PAE #1 SMP
    Norman J. Goldstein, Aug 10, 2013
    #1
    1. Advertising

  2. Norman J. Goldstein

    Ian Collins Guest

    Norman J. Goldstein wrote:
    > The following program compiles and links.
    > No warnings The output is wrong, stating:
    >
    > value= 1
    > value NOT 1
    >
    >
    > //////////////////////////////////////////////
    > #include <iostream>
    > using namespace std;
    >
    > static constexpr int value = 1;
    >
    > int main( int argc, char* argv[] )
    > {
    > cout << "value= "
    > << value
    > << endl;
    >
    > static_assert( value == 1, "Value_Not_1" );
    >
    > #if value == 1
    > cout << "value 1" << endl;
    > #else
    > cout << "value NOT 1" << endl;
    > #endif
    >
    > return 0;
    > }// main
    > /////////////////////////////////////////////////
    >
    > Why is value not used in the conditional compilation?
    > (The static_assert is happy.)


    Because the conditional part is handled by the preprocessor, not the
    compiler. The symbol "value" is unknown to the preprocessor so the first
    condition isn't compiled.

    --
    Ian Collins
    Ian Collins, Aug 10, 2013
    #2
    1. Advertising

  3. On 08/09/2013 09:44 PM, Ian Collins wrote:
    > Norman J. Goldstein wrote:
    >> The following program compiles and links.
    >> No warnings The output is wrong, stating:
    >>
    >> value= 1
    >> value NOT 1
    >>
    >>
    >> //////////////////////////////////////////////
    >> #include <iostream>
    >> using namespace std;
    >>
    >> static constexpr int value = 1;
    >>
    >> int main( int argc, char* argv[] )
    >> {
    >> cout << "value= "
    >> << value
    >> << endl;
    >>
    >> static_assert( value == 1, "Value_Not_1" );
    >>
    >> #if value == 1
    >> cout << "value 1" << endl;
    >> #else
    >> cout << "value NOT 1" << endl;
    >> #endif
    >>
    >> return 0;
    >> }// main
    >> /////////////////////////////////////////////////
    >>
    >> Why is value not used in the conditional compilation?
    >> (The static_assert is happy.)

    >
    > Because the conditional part is handled by the preprocessor, not the
    > compiler. The symbol "value" is unknown to the preprocessor so the first
    > condition isn't compiled.
    >

    Thanks, Ian. I checked using "X" instead of "value", with the same
    result. I think some such capability would be very helpful. The SFINAE
    is well and good in template matching, but is awkward to take advantage
    of in my particular circumstance. The static_assert mechanism shows
    that such conditional compilation is "almost" provided by C++11.
    Norman J. Goldstein, Aug 10, 2013
    #3
  4. Norman J. Goldstein

    Ian Collins Guest

    Norman J. Goldstein wrote:
    > On 08/09/2013 09:44 PM, Ian Collins wrote:
    >> Norman J. Goldstein wrote:


    <snip>

    >>> Why is value not used in the conditional compilation?
    >>> (The static_assert is happy.)

    >>
    >> Because the conditional part is handled by the preprocessor, not the
    >> compiler. The symbol "value" is unknown to the preprocessor so the first
    >> condition isn't compiled.
    >>

    > Thanks, Ian. I checked using "X" instead of "value", with the same
    > result. I think some such capability would be very helpful. The SFINAE
    > is well and good in template matching, but is awkward to take advantage
    > of in my particular circumstance. The static_assert mechanism shows
    > that such conditional compilation is "almost" provided by C++11.


    I think conditional compilation is overrated. There are usually
    (admittedly not always!) more elegant solutions that don't involve the
    preprocessor.

    You could achieve your original goal by resorting to a #define rather
    than a constant for value, but it's still any ugly kludge.

    --
    Ian Collins
    Ian Collins, Aug 10, 2013
    #4
  5. Norman J. Goldstein

    Öö Tiib Guest

    On Saturday, 10 August 2013 07:36:10 UTC+3, Norman J. Goldstein wrote:
    > The following program compiles and links.
    > No warnings The output is wrong, stating:
    >
    > value= 1
    > value NOT 1
    >
    > //////////////////////////////////////////////
    > #include <iostream>
    > using namespace std;
    >
    > static constexpr int value = 1;
    >
    > int main( int argc, char* argv[] )
    > {
    > cout << "value= "
    > << value
    > << endl;
    >
    > static_assert( value == 1, "Value_Not_1" );
    >
    > #if value == 1
    > cout << "value 1" << endl;
    > #else
    > cout << "value NOT 1" << endl;
    > #endif


    I am not sure if above is undefined behavior, but I know no one who
    would accept it in review. You compare undefined macro 'value' with
    1 here.

    > return 0;
    > }// main
    > /////////////////////////////////////////////////
    >
    > Why is value not used in the conditional compilation?
    > (The static_assert is happy.)


    Because 'value' is not macro. 'static_assert' is not done by
    preprocessor, so it works. All compilers I know of (that implement
    'static_assert') optimize that if and the contents of else part
    away from resulting binary when you write it like that:

    //////////////////////////////////////////////
    #include <iostream>
    static constexpr int value = 1;

    int main()
    {
    std::cout << "value= " << value << std::endl;

    static_assert( value == 1, "Value_Not_1" );

    if (value == 1) // <- some compilers may issue silly warnings
    // about condition being always true
    {
    std::cout << "value 1" << std::endl;
    }
    else
    {
    // <- some compilers may issue silly warnings
    // about unreachable code
    std::cout << "value NOT 1" << std::endl;
    }
    }
    /////////////////////////////////////////////////

    So you need to be more specific ... why you need conditional
    compiling here? It only makes code harder to read.
    Öö Tiib, Aug 10, 2013
    #5
  6. On 08/10/2013 01:11 AM, Öö Tiib wrote:
    > ... All compilers I know of (that implement
    > 'static_assert') optimize that if and the contents of else part
    > away from resulting binary when you write it like that:
    >
    > //////////////////////////////////////////////
    > #include <iostream>
    > static constexpr int value = 1;
    >
    > int main()
    > {
    > std::cout << "value= " << value << std::endl;
    >
    > static_assert( value == 1, "Value_Not_1" );
    >
    > if (value == 1) // <- some compilers may issue silly warnings
    > // about condition being always true
    > {
    > std::cout << "value 1" << std::endl;
    > }
    > else
    > {
    > // <- some compilers may issue silly warnings
    > // about unreachable code
    > std::cout << "value NOT 1" << std::endl;
    > }
    > }
    > /////////////////////////////////////////////////
    >
    > So you need to be more specific ... why you need conditional
    > compiling here? It only makes code harder to read.
    >


    Below is source code that illustrates how conditional compilation
    would have been helpful for readability. The template method
    T* NewGuy( T* ptr )
    is to return an independent T ptr, either bay calling new T, or,
    preferably, by calling the method ptr->newGuy(). When ptr is not
    NULL, it is assumed that T::newGuy() exists.

    // Use #f 1 for the One Template Method
    // Use #f 0 for the Two Template Method

    # if 1 /////////// One Template Method /////////////

    // This implementation fails if T is an abstract class,
    // even if the abstract pointer is not NULL. The error
    // is at compile time.

    template< typename T >
    T* NewGuy( const T* ptr = nullptr )
    {
    if( nullptr == ptr )
    {
    return new T;
    }

    return ptr->newGuy();
    }

    # else ////////// Two Template Methods ///////////////

    // This implementation works

    #include "boost/type_traits.hpp"
    #include "assert.h"

    // Accepts only abstract classes
    template< typename T >
    typename std::enable_if< boost::is_abstract<T>::value,
    T* >::type
    NewGuy( const T* ptr )
    {
    assert( ptr != nullptr );

    return ptr->newGuy();
    }

    // Accepts only concrete classes
    template< typename T >
    typename std::enable_if< !boost::is_abstract<T>::value,
    T* >::type
    NewGuy( const T* ptr = nullptr )
    {
    if( nullptr == ptr )
    {
    return new T;
    }

    return ptr->newGuy();
    }

    # endif ////////////////////////////////////////////

    #include <memory>

    struct B
    {
    virtual B* newGuy( void ) const = 0;
    };

    struct A : public B
    {
    A* newGuy( void ) const
    {
    return new A;
    }
    } a;

    int main( int argc, char* argv[] )
    {
    // This fails with the One Template Method
    std::unique_ptr<B> bp( NewGuy( (B*) &a ) );

    return 0;
    }
    Norman J. Goldstein, Aug 10, 2013
    #6
  7. Norman J. Goldstein

    James Kanze Guest

    On Saturday, August 10, 2013 5:44:38 AM UTC+1, Ian Collins wrote:
    > Norman J. Goldstein wrote:
    > > The following program compiles and links.
    > > No warnings The output is wrong, stating:
    > > value= 1
    > > value NOT 1
    > >
    > > //////////////////////////////////////////////
    > > #include <iostream>
    > > using namespace std;
    > >
    > > static constexpr int value = 1;
    > >
    > > int main( int argc, char* argv[] )
    > > {
    > > cout << "value= "
    > > << value
    > > << endl;
    > >
    > > static_assert( value == 1, "Value_Not_1" );
    > >
    > > #if value == 1
    > > cout << "value 1" << endl;
    > > #else
    > > cout << "value NOT 1" << endl;
    > > #endif
    > >
    > > return 0;
    > > }// main
    > > /////////////////////////////////////////////////
    > >
    > > Why is value not used in the conditional compilation?
    > > (The static_assert is happy.)


    > Because the conditional part is handled by the preprocessor, not the
    > compiler. The symbol "value" is unknown to the preprocessor so the first
    > condition isn't compiled.


    To be more exact: when evaluating a preprocessor expression,
    symbols which are unknown to the preprocessor are replaced with
    0.

    --
    Janes
    James Kanze, Aug 11, 2013
    #7
  8. Norman J. Goldstein

    Öö Tiib Guest

    On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    > James Kanze <> wrote:
    > > To be more exact: when evaluating a preprocessor expression,
    > > symbols which are unknown to the preprocessor are replaced with
    > > 0.

    >
    > I think that was a horrible idea from the people who first designed
    > the C preprocessor. But I suppose it's too late to change it now.


    Why? C++ is hopefully going there. First was that dual meaning of
    'const' to get rid of #define constants. That 'const' was fortunately
    fixed by 'constexpr'. 'constexpr' also fixed the remaining issues of
    using inlines instead of macros. Now what is missing is some replacement
    to #include (like modules). Also better debugging support (to replace
    those __LINE__ and __FILE__).
    Öö Tiib, Aug 12, 2013
    #8
  9. Norman J. Goldstein

    Ian Collins Guest

    Juha Nieminen wrote:
    > ?? Tiib <> wrote:
    >> On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    >>> James Kanze <> wrote:
    >>>> To be more exact: when evaluating a preprocessor expression,
    >>>> symbols which are unknown to the preprocessor are replaced with
    >>>> 0.
    >>>
    >>> I think that was a horrible idea from the people who first designed
    >>> the C preprocessor. But I suppose it's too late to change it now.

    >>
    >> Why?

    >
    > What do you mean why? How exactly is it a good thing that unknown
    > symbols are replaced with 0 instead of giving an error message?


    Lots of system headers rely on this behaviour. Whether this is a good
    think or not is open for debate, but it does make sense for checks to
    return false if the value is undefined. I guess checks for __cplusplus
    being greater than some version in a header shared by C and C++ would be
    one example.

    --
    Ian Collins
    Ian Collins, Aug 13, 2013
    #9
  10. Norman J. Goldstein

    Ian Collins Guest

    David Brown wrote:
    > On 13/08/13 07:41, Ian Collins wrote:
    >> Juha Nieminen wrote:
    >>> ?? Tiib <> wrote:
    >>>> On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    >>>>> James Kanze <> wrote:
    >>>>>> To be more exact: when evaluating a preprocessor expression,
    >>>>>> symbols which are unknown to the preprocessor are replaced with
    >>>>>> 0.
    >>>>>
    >>>>> I think that was a horrible idea from the people who first designed
    >>>>> the C preprocessor. But I suppose it's too late to change it now.
    >>>>
    >>>> Why?
    >>>
    >>> What do you mean why? How exactly is it a good thing that unknown
    >>> symbols are replaced with 0 instead of giving an error message?

    >>
    >> Lots of system headers rely on this behaviour. Whether this is a good
    >> think or not is open for debate, but it does make sense for checks to
    >> return false if the value is undefined. I guess checks for __cplusplus
    >> being greater than some version in a header shared by C and C++ would be
    >> one example.
    >>

    >
    > I prefer to enable the gcc "-Wundef" warning in all my code - this turns
    > pre-processor references to undefined macros into warnings rather than
    > 0. gcc disables such warnings for system headers (unless you ask it not
    > to), so it doesn't affect them - and it helps catch bugs in your own
    > code. It's not hard to use "#ifdef XXX" rather than "#if XXX" for
    > symbols that might be undefined.


    Or as C++ programmers, not to use the preprocessor at all! You can't
    use #if for a comparison and comparisons often occur in a complex
    expression so not defined = 0 makes sense.

    --
    Ian Collins
    Ian Collins, Aug 13, 2013
    #10
  11. Norman J. Goldstein

    Ian Collins Guest

    David Brown wrote:
    > On 13/08/13 09:53, Ian Collins wrote:
    >> David Brown wrote:
    >>> On 13/08/13 07:41, Ian Collins wrote:
    >>>> Juha Nieminen wrote:
    >>>>> ?? Tiib <> wrote:
    >>>>>> On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    >>>>>>> James Kanze <> wrote:
    >>>>>>>> To be more exact: when evaluating a preprocessor expression,
    >>>>>>>> symbols which are unknown to the preprocessor are replaced with
    >>>>>>>> 0.
    >>>>>>>
    >>>>>>> I think that was a horrible idea from the people who first designed
    >>>>>>> the C preprocessor. But I suppose it's too late to change it now.
    >>>>>>
    >>>>>> Why?
    >>>>>
    >>>>> What do you mean why? How exactly is it a good thing that unknown
    >>>>> symbols are replaced with 0 instead of giving an error message?
    >>>>
    >>>> Lots of system headers rely on this behaviour. Whether this is a good
    >>>> think or not is open for debate, but it does make sense for checks to
    >>>> return false if the value is undefined. I guess checks for __cplusplus
    >>>> being greater than some version in a header shared by C and C++ would be
    >>>> one example.
    >>>>
    >>>
    >>> I prefer to enable the gcc "-Wundef" warning in all my code - this turns
    >>> pre-processor references to undefined macros into warnings rather than
    >>> 0. gcc disables such warnings for system headers (unless you ask it not
    >>> to), so it doesn't affect them - and it helps catch bugs in your own
    >>> code. It's not hard to use "#ifdef XXX" rather than "#if XXX" for
    >>> symbols that might be undefined.

    >>
    >> Or as C++ programmers, not to use the preprocessor at all! You can't
    >> use #if for a comparison and comparisons often occur in a complex
    >> expression so not defined = 0 makes sense.
    >>

    >
    > Perhaps I am misunderstanding you, but you certainly /can/ use "#if" for
    > comparisons:


    Sorry, I should have written "You can't use #ifdef for a comparison".

    --
    Ian Collins
    Ian Collins, Aug 13, 2013
    #11
  12. Norman J. Goldstein

    Ian Collins Guest

    Fred Zwarts (KVI) wrote:
    > "Ian Collins" wrote in message news:...
    >>
    >> David Brown wrote:
    >>> On 13/08/13 09:53, Ian Collins wrote:
    >>>> David Brown wrote:
    >>>>> On 13/08/13 07:41, Ian Collins wrote:
    >>>>>> Juha Nieminen wrote:
    >>>>>>> ?? Tiib <> wrote:
    >>>>>>>> On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    >>>>>>>>> James Kanze <> wrote:
    >>>>>>>>>> To be more exact: when evaluating a preprocessor expression,
    >>>>>>>>>> symbols which are unknown to the preprocessor are replaced with
    >>>>>>>>>> 0.
    >>>>>>>>>
    >>>>>>>>> I think that was a horrible idea from the people who first designed
    >>>>>>>>> the C preprocessor. But I suppose it's too late to change it now.
    >>>>>>>>
    >>>>>>>> Why?
    >>>>>>>
    >>>>>>> What do you mean why? How exactly is it a good thing that unknown
    >>>>>>> symbols are replaced with 0 instead of giving an error message?
    >>>>>>
    >>>>>> Lots of system headers rely on this behaviour. Whether this is a good
    >>>>>> think or not is open for debate, but it does make sense for checks to
    >>>>>> return false if the value is undefined. I guess checks for
    >>>>>> __cplusplus
    >>>>>> being greater than some version in a header shared by C and C++ would
    >>>>>> be
    >>>>>> one example.
    >>>>>>
    >>>>>
    >>>>> I prefer to enable the gcc "-Wundef" warning in all my code - this
    >>>>> turns
    >>>>> pre-processor references to undefined macros into warnings rather than
    >>>>> 0. gcc disables such warnings for system headers (unless you ask it
    >>>>> not
    >>>>> to), so it doesn't affect them - and it helps catch bugs in your own
    >>>>> code. It's not hard to use "#ifdef XXX" rather than "#if XXX" for
    >>>>> symbols that might be undefined.
    >>>>
    >>>> Or as C++ programmers, not to use the preprocessor at all! You can't
    >>>> use #if for a comparison and comparisons often occur in a complex
    >>>> expression so not defined = 0 makes sense.
    >>>>
    >>>
    >>> Perhaps I am misunderstanding you, but you certainly /can/ use "#if" for
    >>> comparisons:

    >>
    >> Sorry, I should have written "You can't use #ifdef for a comparison".
    >>

    >
    > But you can use
    > #if defined(value) && value == 0


    You missed my earlier point that comparisons often occur in a complex
    expression, so this isn't convenient.

    By way of an example, from stdio.h on my box:

    /*
    * The following are known to POSIX.1c, but not to ANSI-C or XOPEN.
    */
    #if defined(__EXTENSIONS__) || defined(_REENTRANT) || \
    (_POSIX_C_SOURCE - 0 >= 199506L)

    --
    Ian Collins
    Ian Collins, Aug 13, 2013
    #12
  13. Norman J. Goldstein

    Öö Tiib Guest

    On Tuesday, 13 August 2013 08:20:54 UTC+3, Juha Nieminen wrote:
    > ?? Tiib <> wrote:
    >
    > > On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    > >> I think that was a horrible idea from the people who first designed
    > >> the C preprocessor. But I suppose it's too late to change it now.

    > >
    > > Why?

    >
    > What do you mean why? How exactly is it a good thing that unknown
    > symbols are replaced with 0 instead of giving an error message?


    Some compilers and static analyze tools can be set up to warn.
    "Why" in sense "why you suppose that it is too late?". The part you
    snipped tried to elaborate how C++ is actually evolving to reduce
    preprocessor usage.

    I do not like the preprocessor because it is hard to debug it and
    because it is prime source of long compiling times. Average C++
    compilation unit is hundreds of thousands of lines long after
    preprocessing. Mostly pointlessly.
    Öö Tiib, Aug 13, 2013
    #13
  14. Norman J. Goldstein

    James Kanze Guest

    On Tuesday, 13 August 2013 08:00:56 UTC+1, David Brown wrote:
    > On 13/08/13 07:41, Ian Collins wrote:
    > > Juha Nieminen wrote:
    > >> ?? Tiib <> wrote:
    > >>> On Monday, 12 August 2013 14:03:19 UTC+3, Juha Nieminen wrote:
    > >>>> James Kanze <> wrote:
    > >>>>> To be more exact: when evaluating a preprocessor expression,
    > >>>>> symbols which are unknown to the preprocessor are replaced with
    > >>>>> 0.


    > >>>> I think that was a horrible idea from the people who first designed
    > >>>> the C preprocessor. But I suppose it's too late to change it now.


    > >>> Why?


    > >> What do you mean why? How exactly is it a good thing that unknown
    > >> symbols are replaced with 0 instead of giving an error message?


    > > Lots of system headers rely on this behaviour. Whether this is a good
    > > think or not is open for debate, but it does make sense for checks to
    > > return false if the value is undefined. I guess checks for __cplusplus
    > > being greater than some version in a header shared by C and C++ would be
    > > one example.


    > I prefer to enable the gcc "-Wundef" warning in all my code - this turns
    > pre-processor references to undefined macros into warnings rather than
    > 0. gcc disables such warnings for system headers (unless you ask it not
    > to), so it doesn't affect them - and it helps catch bugs in your own
    > code. It's not hard to use "#ifdef XXX" rather than "#if XXX" for
    > symbols that might be undefined.


    Or even "#if defined(XXX) && XXX > 0" (although I'm not sure
    that the preprocessor short circuits, so you might get the
    warning anyway). But I do like the idea of getting a warning.

    --
    James
    James Kanze, Aug 13, 2013
    #14
  15. Norman J. Goldstein

    Guest

    On Monday, August 12, 2013 10:01:05 AM UTC-5, Öö Tiib wrote:
    >
    > Why? C++ is hopefully going there. First was that dual meaning of
    > 'const' to get rid of #define constants. That 'const' was fortunately
    > fixed by 'constexpr'. 'constexpr' also fixed the remaining issues of
    > using inlines instead of macros. Now what is missing is some replacement
    > to #include (like modules). Also better debugging support (to replace
    > those __LINE__ and __FILE__).



    addrinfo* getaddrinfo_wrapper (char const*, int, int, int);

    #define GETADDRINFO_RES(node, port, flags, socktype) \
    auto deleter = [](addrinfo* p) { ::freeaddrinfo(p); }; \
    ::std::unique_ptr<addrinfo, decltype(deleter)> \
    res(getaddrinfo_wrapper(node, port, flags, socktype), deleter);

    This may not be what you mean, but was thinking about changing
    that macro to be an inline function that returns a unique_ptr,
    but don't think I can do that, since deleter wouldn't be in scope.


    Brian
    Ebenezer Enterprises - John 3:16.
    http://webEbenezer.net
    , Aug 13, 2013
    #15
  16. Norman J. Goldstein

    Öö Tiib Guest

    On Tuesday, 13 August 2013 22:26:45 UTC+3, wrote:
    > On Monday, August 12, 2013 10:01:05 AM UTC-5, Öö Tiib wrote:
    > >
    > > Why? C++ is hopefully going there. First was that dual meaning of
    > > 'const' to get rid of #define constants. That 'const' was fortunately
    > > fixed by 'constexpr'. 'constexpr' also fixed the remaining issues of
    > > using inlines instead of macros. Now what is missing is some replacement
    > > to #include (like modules). Also better debugging support (to replace
    > > those __LINE__ and __FILE__).

    >
    >
    > addrinfo* getaddrinfo_wrapper (char const*, int, int, int);
    >
    > #define GETADDRINFO_RES(node, port, flags, socktype) \
    > auto deleter = [](addrinfo* p) { ::freeaddrinfo(p); }; \
    > ::std::unique_ptr<addrinfo, decltype(deleter)> \
    > res(getaddrinfo_wrapper(node, port, flags, socktype), deleter);
    >
    > This may not be what you mean, but was thinking about changing
    > that macro to be an inline function that returns a unique_ptr,
    > but don't think I can do that, since deleter wouldn't be in scope.


    You mean there is some reason why something like that does not work
    better than the macro:

    struct addrinfo;

    typedef std::unique_ptr< addrinfo, void(*)(addrinfo*) > ResPtr;

    inline
    ResPtr makeResPtr(char const* node, int port, int flags, int socktype)
    {
    void freeaddrinfo(addrinfo*);
    addrinfo* getaddrinfo_wrapper (char const*, int, int, int);

    return ResPtr( getaddrinfo_wrapper(node, port, flags, socktype)
    , ::freeaddrinfo);
    }

    // usage:
    // ResPtr res = makeResPtr(node, port, flags, socktype);

    What is the reason?
    Öö Tiib, Aug 13, 2013
    #16
  17. Norman J. Goldstein

    James Kanze Guest

    On Wednesday, 14 August 2013 10:03:14 UTC+1, Juha Nieminen wrote:
    > Ian Collins <> wrote:


    > > Or as C++ programmers, not to use the preprocessor at all!


    > There are certain situations where a preprocessor macro has no good
    > substitute in either C or C++. assert() would be a good example
    > (at least if you want the file and line number of the assertion itself
    > into the message.)


    Even without the line number. The expansion of assert changes
    depending on whether a macro is defined or not, and can change
    several different times in a single translation unit:

    #define NDEBUG
    #include <assert.h>
    // ...
    #undef NDEBUG
    #include <assert.h>
    // critical section, assert slows things down too much...
    #define NDEBUG
    #include <assert.h>

    --
    James
    James Kanze, Aug 14, 2013
    #17
  18. Norman J. Goldstein

    Öö Tiib Guest

    On Monday, 19 August 2013 00:20:11 UTC+3, wrote:
    > On Tue, 13 Aug 2013 06:44:50 -0700 (PDT), Öö Tiib <>
    > >I do not like the preprocessor because it is hard to debug it and
    > >because it is prime source of long compiling times. Average C++
    > >compilation unit is hundreds of thousands of lines long after
    > >preprocessing. Mostly pointlessly.

    >
    > Although that's not really the fault of preprocessing, rather C++'s
    > lack of a proper module concept.


    Lack of proper module concept and lack of proper separation of interface
    from implementation are because we have #include preprocessor
    directive and include files inherited from C already. That helps with the
    problem by causing those multimegabyte files. So it feels fault of
    preprocessing in a way.
    Öö Tiib, Aug 18, 2013
    #18
  19. Norman J. Goldstein

    Öö Tiib Guest

    On Monday, 19 August 2013 06:36:15 UTC+3, wrote:
    > On Sun, 18 Aug 2013 14:46:39 -0700 (PDT), Öö Tiib <>
    > wrote:
    >
    > >On Monday, 19 August 2013 00:20:11 UTC+3, wrote:
    > >> On Tue, 13 Aug 2013 06:44:50 -0700 (PDT), Öö Tiib <>
    > >> >I do not like the preprocessor because it is hard to debug it and
    > >> >because it is prime source of long compiling times. Average C++
    > >> >compilation unit is hundreds of thousands of lines long after
    > >> >preprocessing. Mostly pointlessly.
    > >>
    > >> Although that's not really the fault of preprocessing, rather C++'s
    > >> lack of a proper module concept.

    > >
    > >Lack of proper module concept and lack of proper separation of interface
    > >from implementation are because we have #include preprocessor
    > >directive and include files inherited from C already. That helps with the
    > >problem by causing those multimegabyte files. So it feels fault of
    > >preprocessing in a way.

    >
    > I think that's looking at it backwards. We abuse the #include
    > facility to provide some semblance of interfaces because there is not
    > proper module concept in C++. We may be doing it for historical
    > reasons, but that's not #include's fault.


    Ok, maybe I somehow look at things backwards. Can you say again what
    combination of these claims you suggest:

    1) There was no .c and .h file pairs in C before C++ was designed.
    2) The .c and .h file pairs of C did not cause that more proper
    alternative module support was not designed into C++ language.
    3) Lack of module support in C++ caused that we invented abuse of #include
    directive and .cpp and .hpp file pairs.
    4) Those .cpp and .hpp file pairs were loaned back into C as .c and .h
    file pairs.

    Since AFAIK those claims are all untrue it feels that I perhaps totally
    misunderstand what you are trying to say.
    Öö Tiib, Aug 19, 2013
    #19
  20. Öö Tiib wrote:

    > On Monday, 19 August 2013 06:36:15 UTC+3, wrote:
    >> On Sun, 18 Aug 2013 14:46:39 -0700 (PDT), Öö Tiib <>
    >> wrote:
    >>
    >>>On Monday, 19 August 2013 00:20:11 UTC+3, wrote:
    >>>> On Tue, 13 Aug 2013 06:44:50 -0700 (PDT), Öö Tiib <>
    >>>> >I do not like the preprocessor because it is hard to debug it and
    >>>> >because it is prime source of long compiling times. Average C++
    >>>> >compilation unit is hundreds of thousands of lines long after
    >>>> >preprocessing. Mostly pointlessly.
    >>>>
    >>>> Although that's not really the fault of preprocessing, rather C++'s
    >>>> lack of a proper module concept.
    >>>
    >>>Lack of proper module concept and lack of proper separation of interface
    >>>from implementation are because we have #include preprocessor
    >>>directive and include files inherited from C already. That helps with the
    >>>problem by causing those multimegabyte files. So it feels fault of
    >>>preprocessing in a way.

    >>
    >> I think that's looking at it backwards. We abuse the #include
    >> facility to provide some semblance of interfaces because there is not
    >> proper module concept in C++. We may be doing it for historical
    >> reasons, but that's not #include's fault.

    >
    > Ok, maybe I somehow look at things backwards. Can you say again what
    > combination of these claims you suggest:
    >
    > 1) There was no .c and .h file pairs in C before C++ was designed.
    > 2) The .c and .h file pairs of C did not cause that more proper
    > alternative module support was not designed into C++ language.
    > 3) Lack of module support in C++ caused that we invented abuse of #include
    > directive and .cpp and .hpp file pairs.
    > 4) Those .cpp and .hpp file pairs were loaned back into C as .c and .h
    > file pairs.
    >
    > Since AFAIK those claims are all untrue it feels that I perhaps totally
    > misunderstand what you are trying to say.


    (I'm not him, but anyway...) Maybe

    5) The existence of a preprocessor with its #include directive does not
    in any way prevent the introduction of a proper concept of a 'module'.

    ?

    (FWIW, it may make it seem less necessary, but that's something entirely
    different.)

    Gerhard
    Gerhard Fiedler, Aug 19, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris P
    Replies:
    0
    Views:
    433
    Chris P
    Oct 28, 2003
  2. avishay

    Conditional compilation in VHDL

    avishay, Aug 1, 2005, in forum: VHDL
    Replies:
    4
    Views:
    2,990
    Andy Peters
    Aug 1, 2005
  3. Praveen
    Replies:
    0
    Views:
    348
    Praveen
    Apr 12, 2005
  4. Praveen Ramesh
    Replies:
    2
    Views:
    2,151
    Steven Cheng[MSFT]
    Apr 13, 2005
  5. Alec S.
    Replies:
    10
    Views:
    10,091
    Alec S.
    Apr 16, 2005
Loading...

Share This Page