Limiting function input only to __int64 but not int...

Discussion in 'C++' started by A, Oct 23, 2011.

  1. A

    A Guest

    Is there a way (except overloading) to limit function input to accept
    __int64 but to get a compiler (preferable) or runtime (less preferable)
    error if it is called with int?

    for example:

    void myfunction(__int64 param) // Accepts only __int64 as input and no
    smaller
    {
    }

    myfunction((__int64)1); // Call OK
    myfunction((int)1); // Call fails or better - compiler reports error
     
    A, Oct 23, 2011
    #1
    1. Advertising

  2. A

    Ian Collins Guest

    On 10/24/11 11:28 AM, A wrote:
    > Is there a way (except overloading) to limit function input to accept
    > __int64 but to get a compiler (preferable) or runtime (less preferable)
    > error if it is called with int?
    >
    > for example:
    >
    > void myfunction(__int64 param) // Accepts only __int64 as input and no
    > smaller
    > {
    > }
    >
    > myfunction((__int64)1); // Call OK
    > myfunction((int)1); // Call fails or better - compiler reports error


    You can use a function template to force a link error:

    #include <stdint.h>

    template <typename T> void f( T n );

    template <> void f( int64_t n ) // Specialise for acceptable types
    {
    }

    Or give the function template a body to force a compiler warning:

    template <typename T> void f( T n )
    {
    T tmp = n/0;
    }

    --
    Ian Collins
     
    Ian Collins, Oct 23, 2011
    #2
    1. Advertising

  3. A

    Marc Guest

    "A" wrote:

    > Is there a way (except overloading) to limit function input to accept
    > __int64 but to get a compiler (preferable) or runtime (less preferable)
    > error if it is called with int?


    Assuming that __int64 is not the same type as int.

    with overloading (what's wrong with overloading?):
    void f(long){}
    void f(int)=delete;

    with sfinae:
    template<class T,class=typename std::enable_if<std::is_same<T,long>::value>::type> void f(T){}
     
    Marc, Oct 23, 2011
    #3
  4. A

    A Guest

    Thank you for your answers so far. I was hoping though for something without
    templates. I did found though BOOST_STRONG_TYPEDEF which pretty much does
    this.
     
    A, Oct 24, 2011
    #4
  5. A

    Goran Guest

    On Oct 24, 12:28 am, "A" <> wrote:
    > Is there a way (except overloading) to limit function input to accept
    > __int64 but to get a compiler (preferable) or runtime (less preferable)
    > error if it is called with int?


    Out of curiosity... Why? int "is an" __int64 any way you look at this.
    Why would it matter?

    Goran.
     
    Goran, Oct 24, 2011
    #5
  6. On 24.10.2011 00:28, A wrote:
    > Is there a way (except overloading) to limit function input to accept
    > __int64 but to get a compiler (preferable) or runtime (less preferable)
    > error if it is called with int?


    > for example:
    >
    > void myfunction(__int64 param) // Accepts only __int64 as input and no
    > smaller

    void myfunction(const __int64& param);


    Marcel
     
    Marcel Müller, Oct 24, 2011
    #6
  7. A

    Ian Collins Guest

    On 10/24/11 08:18 PM, Marcel Müller wrote:
    > On 24.10.2011 00:28, A wrote:
    >> Is there a way (except overloading) to limit function input to accept
    >> __int64 but to get a compiler (preferable) or runtime (less preferable)
    >> error if it is called with int?

    >
    >> for example:
    >>
    >> void myfunction(__int64 param) // Accepts only __int64 as input and no
    >> smaller

    > void myfunction(const __int64& param);


    Won't the normal promotion rules still apply?

    myfunction( 2 );

    Compiles happily as does

    int n = 0;
    myfunction( n );

    --
    Ian Collins
     
    Ian Collins, Oct 24, 2011
    #7
  8. A

    Ian Collins Guest

    On 10/24/11 08:53 PM, Ian Collins wrote:
    > On 10/24/11 08:18 PM, Marcel Müller wrote:
    >> On 24.10.2011 00:28, A wrote:
    >>> Is there a way (except overloading) to limit function input to accept
    >>> __int64 but to get a compiler (preferable) or runtime (less preferable)
    >>> error if it is called with int?

    >>
    >>> for example:
    >>>
    >>> void myfunction(__int64 param) // Accepts only __int64 as input and no
    >>> smaller

    >> void myfunction(const __int64& param);

    >
    > Won't the normal promotion rules still apply?
    >
    > myfunction( 2 );
    >
    > Compiles happily as does
    >
    > int n = 0;
    > myfunction( n );


    Hit send too soon, I was going to add that

    void myfunction( int64_t& param );

    was probably what you intended to type.

    --
    Ian Collins
     
    Ian Collins, Oct 24, 2011
    #8
  9. Ian Collins <> wrote:
    > Or give the function template a body to force a compiler warning:
    >
    > template <typename T> void f( T n )
    > {
    > T tmp = n/0;
    > }


    I don't think that's a very good idea.
     
    Juha Nieminen, Oct 24, 2011
    #9
  10. A

    none Guest

    In article <4ea51cef$0$2800$>,
    Juha Nieminen <> wrote:
    >Ian Collins <> wrote:
    >> Or give the function template a body to force a compiler warning:
    >>
    >> template <typename T> void f( T n )
    >> {
    >> T tmp = n/0;
    >> }

    >
    > I don't think that's a very good idea.


    A compile time assertion would be a bit safer.
     
    none, Oct 24, 2011
    #10
  11. A

    A Guest

    "Goran" <> wrote in message
    news:...
    >Out of curiosity... Why? int "is an" __int64 any way you look at this.
    >Why would it matter?


    because function requires explicitly __int64 because ID's are 64-bit,
    providing 32-bit int would ruin ID's that go over the 32-bit boundary. This
    may happen when I do text-to-int conversions using StrToInt and forget to
    put StrToInt64 instead.

    In Borlangearcadero C++ Builder 2010 which I use, these functions output int
    and __int64 so compiler SHOULD be able to check these but unfortunately it
    doesn't - even if I enable W8102 Implicit conversion of '%s' to '%s' (C++)
    but it doesn't do what it is supposed to. I tried casting to wrong type but
    the warning is still not triggered.
     
    A, Oct 24, 2011
    #11
  12. On 10/24/11 1:17 PM, Robert Wessel wrote:
    > On Mon, 24 Oct 2011 17:11:48 +0200, "A"<> wrote:
    >
    >>
    >> "Goran"<> wrote in message
    >> news:...
    >>> Out of curiosity... Why? int "is an" __int64 any way you look at this.
    >>> Why would it matter?

    >>
    >> because function requires explicitly __int64 because ID's are 64-bit,
    >> providing 32-bit int would ruin ID's that go over the 32-bit boundary. This
    >> may happen when I do text-to-int conversions using StrToInt and forget to
    >> put StrToInt64 instead.
    >>
    >> In Borlangearcadero C++ Builder 2010 which I use, these functions output int
    >> and __int64 so compiler SHOULD be able to check these but unfortunately it
    >> doesn't - even if I enable W8102 Implicit conversion of '%s' to '%s' (C++)
    >> but it doesn't do what it is supposed to. I tried casting to wrong type but
    >> the warning is still not triggered.

    >
    >
    > Why not use the usual trick of imbedding the handle in a structure?
    >
    > struct MyHandle(__int64 h;};
    >
    > And use a MyHandle as the parameter or return value?
    >
    > Alternatively, explicitly declare forms for those functions using int,
    > short, etc., and then never define them - that way the link will fail.
    > Better yet, if your compiler supports the new standard, use the
    > "=delete" form:
    >
    > void f(__int64); //supply actual definition
    > void f(int)=delete; //can't be called
    >
    > Of course that's ugly because of the number of definitions you need to
    > supply to cover all of the usual conversions.


    Actually, once you define one disallowed form, the rest become
    ambiguous. For example, calling with a "short" neither short->int or
    short->__int64 has a preference, so I believe it should give an error. I
    don't think the =delete removes that version from overload resolution,
    but I haven't looked at it in detail yet.
     
    Richard Damon, Oct 24, 2011
    #12
  13. A

    A Guest

    "Robert Wessel" <> wrote in message
    news:...
    > void f(__int64); //supply actual definition
    > void f(int)=delete; //can't be called


    I actually like this solution but the compiler doesn't support it. I guess
    I'll be looking for alternate solutions.
     
    A, Oct 24, 2011
    #13
  14. On 10/24/11 6:12 PM, A wrote:
    > "Robert Wessel"<> wrote in message
    > news:...
    >> void f(__int64); //supply actual definition
    >> void f(int)=delete; //can't be called

    >
    > I actually like this solution but the compiler doesn't support it. I guess
    > I'll be looking for alternate solutions.
    >
    >


    if it doesn't support the =delete syntax, declaring (but not defining)
    void f(unsigned char); (choose an integer type that you are actually
    unlikely to mistakenly use) will make a call of f(1) ambiguous and thus
    an error. You want to make the undefined type an unlikely mistake as if
    you use it by mistake, you are just going to get a link error, and you
    will have to search to find where it is actually called.
     
    Richard Damon, Oct 25, 2011
    #14
  15. A

    Arne Mertz Guest

    On Oct 25, 7:27 am, Christian Gollwitzer <> wrote:
    > Maybe it supports #pragma error?
    > Then you can write


    #pragma error is not very portable, e.g. MSVC does not
    sopport it, instead, it issues a warning about the
    unsupported pragma and happily continues compiling,
    i.e. f(int) may be called.

    overloading f(int) and f(__int64) imo is not a good idea,
    because once you port the whole thing to a 64 bit machine
    int and __int64 become the same and you get either a
    redefinition error (if you actually defined f(int)), or
    the whole "error detection via link error or ambiguity"
    magically dissapears if you only declared f(int), as it
    is just another declaration of f(__int64).
    In your case the latter behavior may be ok, if the
    problem is only about disambiguating 32 bit int and __in64
    in 32 bit systems. But maybe StrToInt outputs __int32
    even on 64 bit systems or something similar happens so you
    want to keep up the 32 bit integer detection even on 64 bit
    systems.

    To make things short(er), I would use overloading, but not
    with any specific integer type but with a template:
    given f(__int64) as the function to be called only for
    64bit types, you have several variants

    Variant a)
    template <typename T>
    void f(T) = delete; //overload resolution calls this for
    any T that is not the same as __int64

    Variant b), C++0x without deleted functions
    template <typename T>
    void f(T)
    { static_assert(false, "call f only with __int64!"); }

    Variant c), C++0x, less restrictive
    #include <type_traits>
    template <typename T>
    f(T t) -> decltype(f(__int64))
    {
    // assert T is "sufficiently close to" __int64
    static_assert(std::is_integral<T>::value
    && std::is_convertible<T, __int64>::value
    && sizeof(T) >= sizeof(__int64));

    return f(__int64(t));
    }

    If your compiler lacks support for static_assert, you
    could use either std::enable_if or the STATIC_ASSERT
    macro from the loki library. If your standard library
    has no <type_traits>, boost provides similar utilities.

    HTH Arne
     
    Arne Mertz, Oct 26, 2011
    #15
    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. Schnoffos
    Replies:
    2
    Views:
    1,246
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,697
    Old Wolf
    Jan 20, 2004
  3. Kio

    __int64 convert to int

    Kio, Feb 27, 2006, in forum: C++
    Replies:
    4
    Views:
    457
  4. Replies:
    9
    Views:
    460
    James Kanze
    Apr 17, 2007
  5. Steve Hicks
    Replies:
    2
    Views:
    1,299
Loading...

Share This Page