A C++ feature I would love to have: custom type modifiers


In C++ the const type mod­i­fiers when applied to meth­ods has the nice prop­erty of mak­ing it impos­si­ble by default (e.g. with­out a const_cast) to call non-const meth­ods. A sim­i­lar fea­ture is pro­vided by C++0x key­word con­s­t­expr.

It would be very nice if this prop­erty could be applied to cus­tom classes of func­tions. The idea would be to tag method def­i­n­i­tions with a cus­tom key­word, or a type. Tagged meth­ods would then only be able to call method tagged with the same type.

A nice usage I could find for this would be to define a non-blocking class of meth­ods. Non block­ing meth­ods are such if they never blocks for a poten­tially unbounded amount of time wait­ing for an event. Using the tags the com­piler will be able to detect if a method sup­posed to be non-blocking is try­ing to call some poten­tially block­ing code and this would be very use­ful to detect pos­si­ble dead­locks at com­pile time. Another usage would be to tag all the meth­ods that are sup­posed to be used by a spe­cific thread with the same tag. With such setup meth­ods that access shared data would be untagged and using them would require a cast or some spe­cial syn­tax, hope­fully help­ing the pro­gram­mer remem­ber that some syn­chro­niza­tion is needed.

A pos­si­ble approach to (ab)use the volatile key­word to detect race con­di­tions was described here in 2001. But maybe this approach could be more gen­eral. Any com­ment?

Flattr this

, ,

  • http://www.timonvo.com Timon Van Overveldt

    I think this is a very inter­est­ing idea. I guess the imple­men­ta­tion in com­pil­ers wouldn’t be that hard since all the func­tion­al­ity is already there.
    I bet that if you ask some peo­ple they can come up with a dozen of handy ways this could be used.

  • http://www.timonvo.com Timon Van Overveldt

    I think this is a very inter­est­ing idea. I guess the imple­men­ta­tion in com­pil­ers wouldn’t be that hard since all the func­tion­al­ity is already there.
    I bet that if you ask some peo­ple they can come up with a dozen of handy ways this could be used.

  • Alex

    What you want is actu­ally some­thing a lit­tle more gen­eral called “Gen­er­al­ized Alge­braic Datatypes” or GADTs. They’re well-known (though some­what new) in type the­ory (which is the field study­ing the kinds of things you ask ;) ) and the Func­tional Pro­gram­ming com­mu­nity, esp. Haskell. Though some­what tech­ni­cal, look here: http://www.haskell.org/haskellwiki/Generalised_algebraic_datatype
    Specif­i­cally at “Exam­ple with lists” for a sim­i­lar exam­ple to what you want with non-blocking. The idea is that you use an arbi­trary datatype-constructor to pass in (through a mech­a­nism sim­i­lar to Phan­tom types) an extra implicit argu­ment that rep­re­sents the “tag” for the GADT that you’re tar­get­ing. Sorry if I’m not being clear, but the minu­tiae of type the­ory and GADTs are tricky. ^^;

  • Alex

    What you want is actu­ally some­thing a lit­tle more gen­eral called “Gen­er­al­ized Alge­braic Datatypes” or GADTs. They’re well-known (though some­what new) in type the­ory (which is the field study­ing the kinds of things you ask ;) ) and the Func­tional Pro­gram­ming com­mu­nity, esp. Haskell. Though some­what tech­ni­cal, look here: http://www.haskell.org/haskellwiki/Generalised_algebraic_datatype
    Specif­i­cally at “Exam­ple with lists” for a sim­i­lar exam­ple to what you want with non-blocking. The idea is that you use an arbi­trary datatype-constructor to pass in (through a mech­a­nism sim­i­lar to Phan­tom types) an extra implicit argu­ment that rep­re­sents the “tag” for the GADT that you’re tar­get­ing. Sorry if I’m not being clear, but the minu­tiae of type the­ory and GADTs are tricky. ^^;

  • Sean

    At the very least, you can use c++0x attrib­utes and GCC plu­g­ins to achieve this.

    Using some macros you can eas­ily make this some­thing you enable only for builds where it’s supported.

    #if defined(NONBLOCKING_CHECK_PLUGIN)
    # define NONBLOCKING [[nonblocking_call]]
    #else
    # define NONBLOCKING
    #endif

    class Foo {
    pub­lic:
    void bar (void* baz) NONBLOCKING { blocking_call(baz); } // error
    };

    gcc –fnonblockingcheck.so –c foo.cc

    The block­ing check plu­gin would define the NONBLOCKING_CHECK_MACRO implic­itly, and then add the seman­tic analy­sis for nonblocking_call functions.

    Tech­ni­cally you don’t even need c++0x attrib­utes, you can just use GCC attrib­utes in this case since it’d be a GCC-only plu­gin. If you wanted to pro­pose it as a patch for Clang though you might want to use the more stan­dard­ized syntax.

    With a lit­tle effort, you could gen­er­al­ize this too. Make the plu­gin load a list of con­text attrib­utes and poli­cies, some­thing like SELinux. Func­tions defined with con­text A can only call func­tions with con­text A or B, and can­not be called from any func­tion with con­text C, etc.

  • Sean

    At the very least, you can use c++0x attrib­utes and GCC plu­g­ins to achieve this.

    Using some macros you can eas­ily make this some­thing you enable only for builds where it’s supported.

    #if defined(NONBLOCKING_CHECK_PLUGIN)
    # define NONBLOCKING [[nonblocking_call]]
    #else
    # define NONBLOCKING
    #endif

    class Foo {
    pub­lic:
    void bar (void* baz) NONBLOCKING { blocking_call(baz); } // error
    };

    gcc –fnonblockingcheck.so –c foo.cc

    The block­ing check plu­gin would define the NONBLOCKING_CHECK_MACRO implic­itly, and then add the seman­tic analy­sis for nonblocking_call functions.

    Tech­ni­cally you don’t even need c++0x attrib­utes, you can just use GCC attrib­utes in this case since it’d be a GCC-only plu­gin. If you wanted to pro­pose it as a patch for Clang though you might want to use the more stan­dard­ized syntax.

    With a lit­tle effort, you could gen­er­al­ize this too. Make the plu­gin load a list of con­text attrib­utes and poli­cies, some­thing like SELinux. Func­tions defined with con­text A can only call func­tions with con­text A or B, and can­not be called from any func­tion with con­text C, etc.

  • Asfrap_neiu

    You can see mon­ads in haskell as some­thing sim­il­iar. For exam­ple to divide into pure and impure func­tions the IO monad is used

  • Asfrap_neiu

    You can see mon­ads in haskell as some­thing sim­il­iar. For exam­ple to divide into pure and impure func­tions the IO monad is used

  • Manuel López-Ibáñez

    You can cre­ate a GCC plu­gin that han­dles a user-defined attribute:

    http://gcc.gnu.org/onlinedocs/gccint/Plugins.html

    The dif­fi­cult part would depend on exactly what you want to imple­ment. Don’t be afraid to pro­pose any enhance­ments to the plu­gin API that you may need, it is FAR from complete!

  • Manuel López-Ibáñez

    You can cre­ate a GCC plu­gin that han­dles a user-defined attribute:

    http://gcc.gnu.org/onlinedocs/gccint/Plugins.html

    The dif­fi­cult part would depend on exactly what you want to imple­ment. Don’t be afraid to pro­pose any enhance­ments to the plu­gin API that you may need, it is FAR from complete!

  • Karl Chen

    You want CQual++. It allows defin­ing cus­tom type qual­i­fiers and also infers them.

  • Karl Chen

    You want CQual++. It allows defin­ing cus­tom type qual­i­fiers and also infers them.

A C++ feature I would love to have: custom type modifiers


In C++ the const type mod­i­fiers when applied to meth­ods has the nice prop­erty of mak­ing it impos­si­ble by default (e.g. with­out a const_cast) to call non-const meth­ods. A sim­i­lar fea­ture is pro­vided by C++0x key­word con­s­t­expr.

It would be very nice if this prop­erty could be applied to cus­tom classes of func­tions. The idea would be to tag method def­i­n­i­tions with a cus­tom key­word, or a type. Tagged meth­ods would then only be able to call method tagged with the same type.

A nice usage I could find for this would be to define a non-blocking class of meth­ods. Non block­ing meth­ods are such if they never blocks for a poten­tially unbounded amount of time wait­ing for an event. Using the tags the com­piler will be able to detect if a method sup­posed to be non-blocking is try­ing to call some poten­tially block­ing code and this would be very use­ful to detect pos­si­ble dead­locks at com­pile time. Another usage would be to tag all the meth­ods that are sup­posed to be used by a spe­cific thread with the same tag. With such setup meth­ods that access shared data would be untagged and using them would require a cast or some spe­cial syn­tax, hope­fully help­ing the pro­gram­mer remem­ber that some syn­chro­niza­tion is needed.

A pos­si­ble approach to (ab)use the volatile key­word to detect race con­di­tions was described here in 2001. But maybe this approach could be more gen­eral. Any com­ment?

Flattr this

, ,