c++11 - c++ - Must all static class methods be defined, even when not used? -


so, i've got issue, , i'm not sure if it's language issue, or compiler/gcc issue.

tl;dr - required define static methods within class, if static methods never called application (i.e. legitimately dropped linker anyway)?

i have library class implements device driver uart in microcontroller. because don't want multiple uart objects pointing same resource, each uart object singleton, retrieved using 1 of several getinstance() methods, 1 each uart instance in device (uart0, uart1, etc). each uart instance needs have 2 fifos (tx , rx) storage. each fifo needs explicitly sized application , allocated @ time uart object instantiated (ideally). have several static getstorage() methods, again, once each uart.

i've created stripped down code proof of concept. here's static_instance.h:

#ifndef static_instance_h_ #define static_instance_h_  #ifdef __cplusplus #include <vector> namespace foo { class uart {  public:   /* retrieve singleton instance, using lazy static initialization.  note    * not instances present given device. */   static uart& uart1getinstance(void);   static uart& uart2getinstance(void);   static uart& uart3getinstance(void);   /* something. */   void dosomething(void) { ++counter; }  private:   /* structure storage each static uart instance requires. */   struct storage {     storage(std::vector<char>& vector)         : my_vector_(vector) { }     std::vector<char>& my_vector_;   // buffer data.   };   /* instantiate object using provided register base , fifo structures. */   uart(int instance, storage& storage)       : instance_(instance), storage_(storage) { }   ~uart() { }   /* retrieves storage required static uart object instances.    * these methods not implemented in static_instance.cc, must    * implemented in application code, uart instances    * invoked in application. */   static storage& uart1getstorage(void);   static storage& uart2getstorage(void);   static storage& uart3getstorage(void);   int const instance_;    // instance number of object.   storage& storage_;      // allocated storage object.   int counter = 0;        // dummy counter. }; } // namespace foo #endif  // __cplusplus  #endif 

and here's static_instance.cc:

#include <static_instance.h> namespace foo {  uart& uart::uart1getinstance(void) {   static uart uart(1, uart1getstorage());   return uart; } uart& uart::uart2getinstance(void) {   static uart uart(2, uart2getstorage());   return uart; } uart& uart::uart3getinstance(void) {   static uart uart(3, uart3getstorage());   return uart; }  } // namespace foo 

the idea call getinstance() uart instance need, , define getstorage() uart instance. (for example, i'm defining 1 buffer, , using std::vector<char> stand-in.) further, it's left application define storage method, because each application going have own requirements how big given uart's buffer needs be. (what absolutely won't put macros in c++ module, because, ew.) here's code snippet in main.cc instantiate uart2:

namespace foo {  uart::storage& uart::uart2getstorage(void) {   static std::vector<char> rx_vector(256, 0);   static uart::storage storage(rx_vector);   return storage; } static foo::uart& uart_ = foo::uart::uart2getinstance(); void wibble(void) {   uart_.dosomething(); }  } // namespace foo 

now, developing earlier application using earlier ide chip (kinetis design studio v3.2.0 curious), uses gcc 4.8.4 , compiles , links no errors.

but nxp has deprecated kds toolchain (mcuxpresso 10.0), uses gcc 5.4.1, , using exact same code, time two linker errors:

./source/static_instance.o: in function 'foo::uart::uart1getinstance()': ../source/static_instance.cc:5: undefined reference 'foo::uart::uart1getstorage()' ./source/static_instance.o: in function 'foo::uart::uart3getinstance()': ../source/static_instance.cc:13: undefined reference 'foo::uart::uart3getstorage()' 

i'm not sure why linker cares getstorage() methods uart1 , uart3 aren't defined, because i'm not calling getinstance() either uart1 or uart3 in application, , never calling corresponding getstorage() methods either.

my question here is... c++11 require me have 3 storage methods defined in executable? is, gcc 4.8.4 letting me away shouldn't have been able to? or gcc 5.4 option need toggle, allow me drop unused static members class?

if answer "you have define them regardless", i'll define them, or maybe engineer other way allow. if answer "that should ok", , there's no option can set on command line make gcc 5.4 it, i'll take next step , report bug in nxp forums. thanks.

tl;dr - required define static methods within class, if static methods never called application

you may required define such static methods, if never called application.

but, in general, might not need to, if functions not odr-used (one definition rule). static member functions, equivalent to

a function name appears potentially-evaluated expression

the difference subtle. hope demonstrates it:

if(false)     function(); 

function never called, appears in potentially-evaluated expression, , therefore odr-used , therefore must defined.


my question here is... c++11 require me have 3 storage methods defined in executable?

yes. appear in potentially-evaluated expressions , therefore odr-used , therefore must defined.

i developing earlier application using ... gcc 4.8.4 , compiles , links no errors.

odr violations have undefined behaviour, explains why didn't error / warning in other tool chain.


Comments

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -