реклама на сайте
подробности

 
 
> GCC Warning: left shift count >= width of type
Pavel V.
сообщение Feb 10 2012, 18:44
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-06-06
Пользователь №: 17 742



Компилирую следующий код:

Код
template<uint32_t pin>
class Pin
{
public:
    void Test()
    {
        if(pin < 16) {
1:            g_test &= ~(0x03UL << (pin * 2));
        }
        else
        {
            g_test &= ~(0x03UL << ((pin - 16) * 2));
        }
    }
};

int main()
{
    Pin<22> test;
    test.Test();
}


На строчку 1 компилятор ругается:

Код
source/main.cpp: In member function 'void Pin<pin>::Test() [with long unsigned int pin = 22ul]':
source/main.cpp:30:12:   instantiated from here
source/main.cpp:18:4: warning: left shift count >= width of type [enabled by default]


Код компилируется и работает правильно. Оптимизатор, естественно, выкидывает ненужный код, т.к. pin константа (что видно по листингу).
Как убрать это сообщение?


--------------------
Good News Everyone!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
neiver
сообщение Feb 10 2012, 20:27
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Для этого можно использовать частичную специализацию шаблонов. Завести дополнительную шаблонный класс, вычисляющий нужную маску и сделать для него две специализации, для pin < 16 и для pin >= 16.
Код
template<uint32_t pin>
class Pin
{
// warning: brain-compiled code ahead
   template<bool pinLessThen16>
   struct Mask
   {
      enum {value =  ~(0x03UL << (pin * 2)) };
   };

   template<>
   struct Mask<false>
   {
      enum {value =  ~(0x03UL << ((pin - 16) * 2)) };
   };

public:
    void Test()
    {
      g_test &= Mask<(pin < 16)>::value;
    }
};
Go to the top of the page
 
+Quote Post
Pavel V.
сообщение Feb 11 2012, 16:11
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 3-06-06
Пользователь №: 17 742



Цитата(neiver @ Feb 11 2012, 00:27) *
Для этого можно использовать частичную специализацию шаблонов. Завести дополнительную шаблонный класс, вычисляющий нужную маску и сделать для него две специализации, для pin < 16 и для pin >= 16.

Спасибо за идею! В итоге так и сделал, только использовал анонимный параметр, что избавило от необходимости в вызове писать условие pin < 16.
Специализацию шаблона нельзя выполнять внутри класса, поэтому вынес наружу.

Код
namespace IO
{
    template<uint32_t pin, bool = (pin < 16)>
    struct ConfigurationMask
    {
        static inline uint32_t Clear() { return ~(0x03UL << (pin * 2)); }
        static inline uint32_t SelSet(Configuration configuration) { return (((uint32_t)configuration >> 4) & 0x03UL) << (pin * 2); }
        static inline uint32_t ModeSet(Configuration configuration) { return (((uint32_t)configuration >> 2) & 0x03UL) << (pin * 2); }
    };

    template<uint32_t pin>
    struct ConfigurationMask<pin, false>
    {
        static inline uint32_t Clear() { return ~(0x03UL << ((pin - 16) * 2)); }
        static inline uint32_t SelSet(Configuration configuration) { return (((uint32_t)configuration >> 4) & 0x03UL) << ((pin - 16) * 2); }
        static inline uint32_t ModeSet(Configuration configuration) { return (((uint32_t)configuration >> 2) & 0x03UL) << ((pin - 16) * 2); }
    };

    template<Port port, uint32_t pin, ActiveState activestate>
    class Pin
    {
        static_assert((pin < 32), "Pin number must be <= 31");

    public:
        /*
         * Set Configuration
         */
        static void SetConfiguration(Configuration configuration)
        {
            ...
            SEL0 &= ConfigurationMask<pin>::Clear();
            SEL0 |= ConfigurationMask<pin>::SelSet(configuration);
            MODE0 &= ConfigurationMask<pin>::Clear();
            MODE0 |= ConfigurationMask<pin>::ModeSet(configuration);
            ...
        }
    };
}


--------------------
Good News Everyone!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 03:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01708 секунд с 7
ELECTRONIX ©2004-2016