CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Program-unique values

    I'm looking for a way to generate a program-wide unique value to use as a template parameter. Generating a unique value within a translation unit is pretty easy with __LINE__, but that doesn't ensure uniqueness across translation units. I thought maybe I could use __FILE__, but that can't be used as a template parameter.

    I stumbled across this page:
    http://stackoverflow.com/questions/1...unique-numbers

    which is exactly what I want, except that the anonymous namespace trick doesn't work on all the compilers I've tried it on. (This may be due to C++11 changing anonymous namespaces to internal linkage rather than external as they did before....that page is five years old.)

    Any suggestions? Preferably ones that work with C++03 and C++11, but I'll take pure-C++11 options too, since the above seems to work for older systems.

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Program-unique values

    I'm not sure I got what you mean by "a program-wide unique value to use as a template parameter", do you mean something like this ?

    Code:
    namespace some_name_space {
    template< unsigned lineid, unsigned I = 0, char c = __FILE__[I] >
    struct unique_type: unique_type<lineid,I+1> {};
    
    template< unsigned lineid>
    struct unique_type<lineid,sizeof(__FILE__)-1,0> {};
    }
    
    // unique_type<__LINE__> this type is "unique" to this line/file name pair; this can be used as a template parameter directly, or used to compute an id somehow ...
    Last edited by superbonzo; October 14th, 2014 at 07:39 AM. Reason: fixed typo as noted in post #5

  3. #3
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Program-unique values

    Quote Originally Posted by Lindley View Post
    I'm looking for a way to generate a program-wide unique value to use as a template parameter.
    It is doable, but at the same time it's a pretty good indication you're trying to do something that's got an inherrent design flaw.
    The point of templates afterall is generic reuse, what you're asking pretty much boils down to enforced unique instantiation.

    the solution depends on how "deep" you need this to work. Does it only need to work on a single file, or on a set of files in a project (a single exe/dll/library) or does it need to work cross multiple dll's/exe's?
    Last edited by OReubens; October 14th, 2014 at 07:14 AM.

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Program-unique values

    Quote Originally Posted by superbonzo View Post
    I'm not sure I got what you mean by "a program-wide unique value to use as a template parameter", do you mean something like this ?

    Code:
    namespace {
    template< unsigned lineid, unsigned I = 0, char c = __FILE__[I] >
    struct unique_type: unique_type<lineid,I+1> {};
    
    template< unsigned lineid>
    struct unique_type<lineid,sizeof(__FILE__)-1,0> {};
    }
    
    // unique_type<__LINE__> this type is "unique" to this line/file name pair; this can be used as a template parameter directly, or used to compute an id somehow ...
    are you sure this works ?
    I would assume __FILE__ wil Always end up holding the name of the template header, not the name of the topmost file in the include chain.

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Program-unique values

    Quote Originally Posted by OReubens View Post
    are you sure this works ?
    I would assume __FILE__ wil Always end up holding the name of the template header, not the name of the topmost file in the include chain.
    if it appears in an header as is, yes, but you can always redeclare it in each and every file where's needed ( eventually with the help of a macro; actually note there's a typo in my post: the unnamed namespace declaration actually was meant to be something like "namespace some_name_space {" where "some_name_space" is supposed to be replaced by something related to the file ( or group of files, whatever ) to which that template refers to ).

    me too, I don't know exactly what's the expected purpose/behavior of this "unique" value ... hence I don't know how the OP expects this to behave wrt what/when is included where

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Program-unique values

    Quote Originally Posted by superbonzo View Post
    I'm not sure I got what you mean by "a program-wide unique value to use as a template parameter", do you mean something like this ?

    Code:
    namespace some_name_space {
    template< unsigned lineid, unsigned I = 0, char c = __FILE__[I] >
    struct unique_type: unique_type<lineid,I+1> {};
    
    template< unsigned lineid>
    struct unique_type<lineid,sizeof(__FILE__)-1,0> {};
    }
    
    // unique_type<__LINE__> this type is "unique" to this line/file name pair; this can be used as a template parameter directly, or used to compute an id somehow ...
    That's an interesting idea, but I'm not convinced it will work....if two files start with the same letter but have different second letters, then (assuming identical lines) you'd end up with the same type being declared with different parent types. Maybe if you wrap it in an anonymous namespace....but even then I'm doubtful. Worth a try though.

    As far as what this is for, our product needs to build on a bunch of different platforms, with varying levels of C++11 support. Therefore we have a macro to make sure that a local static object is thread-safely initialized. Unfortunately, one of our platforms has a bug that makes any non-POD local static extra *unsafe*, so I'm trying to simulate a local static with a global that is uniquely and automatically linked to the point of macro declaration. Since the macro is invoked within a function, and I need a global associated with that line, therefore templates.

  7. #7
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Program-unique values

    Would generating UUIDs be acceptable? It's manual, but it is real stable and works on all platforms.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  8. #8
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Program-unique values

    Quote Originally Posted by Lindley View Post
    That's an interesting idea, but I'm not convinced it will work....if two files start with the same letter but have different second letters, then (assuming identical lines) you'd end up with the same type being declared with different parent types.
    you're totally right; otherwise, the namespace should be unique to the file in which the template is declared ( which may or may not suit your usecase depending on how/where you declare the global ) with the help of a macro ( to be put on top of every file using the facility, ala include guards ); there's also the issue of files with the same name ( this is not so rare, thinking about it ).

    Would you mind posting an example of how the static is emulated exactly ?

    also, I agree with monarch_dodra, UUID's could be a simpler solution after all.
    Last edited by superbonzo; October 16th, 2014 at 02:40 AM.

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Program-unique values

    UUIDs would be great, except that I don't think there's an easy way to generate them at compile time......

    Another approach is to declare a function-local type everywhere I want a static, and use that to instantiate the template. However, that's only allowed under C++11.

    Anyway, I've taken a further look at my original approach based on the Stackoverflow article, and it actually appears to be working. Further analysis showed that what I though was my code failing was actually a bug in the version of clang I was using. I'm hopeful that upgrading it may take care of the issue.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured