Как убрать предупреждения компилятора

b707
Offline
Зарегистрирован: 26.05.2017

вопросик для Песочницы

Имею структуру

typedef struct { 
	uint8_t  *bitmap;     
	uint8_t  *glyph;       
	uint8_t   first;      
        uint8_t   last;       
	uint8_t   yAdvance;  
}Xfont; 

инициализирую ее такими значениями

const Xfont GG_rus PROGMEM = {
  (uint8_t  * ) A_rus,
  (uint8_t  * ) B_rus,
  0x410, 0x44F, 25 };

и естесственно, получаю предупреждение от компилятора, что 3-й и 4-й параметр "не влазят" в отведенный им тип: "warning: narrowing conversion of"

На самом деле, ситуация меня полностью устраивает - от параметров first и last мне нужен только младший байт. Вопрос в следующем - как избавится от этих предупреждений, если менять ни структуру, ни значения я не могу? Так сказать типичная проблема новичка - как правильно сделать неправильную вещь? :)

 

mixail844
Offline
Зарегистрирован: 30.04.2012
const Xfont GG_rus PROGMEM = {
  (uint8_t  * ) A_rus,
  (uint8_t  * ) B_rus,
  (uint8_t)(0x410 & 0xFF),(uint8_t)( 0x44F & 0xFF), 25 };

 

b707
Offline
Зарегистрирован: 26.05.2017

mixail844 пишет:

const Xfont GG_rus PROGMEM = {
  (uint8_t  * ) A_rus,
  (uint8_t  * ) B_rus,
  (uint8_t)(0x410 & 0xFF),(uint8_t)( 0x44F & 0xFF), 25 };

 

тогда проще стереть верхний байт, да и все :) -  0x410 => 0x10

Проблема в том, что таких фонтов куча и в каждом придется править

Ладно, я уже понял, что вопрос глупый. Но для этого его нужно было задать :)

rkit
Offline
Зарегистрирован: 23.11.2016

Указатели на оперативку в PROGMEM хранить тоже странновато.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

Ладно, я уже понял, что вопрос глупый. Но для этого его нужно было задать :)

Ну, почему? Вопрос - как вопрос.

Насколько Вы не можете менять структуру? Вообще прикасаться нельзя или только размер и порядок полей трогать нельзя, а прикоснуться-то можно?

Если прикоснуться таки можно, то как два пальца. Добавьте в структуру конструктор с пятью параметрами и эти два сделайте 16-битными, а в конструкторе присвойте их восьмибитным членам с аккуратным отбрасыванием. Все Ваши 100500 уже готовых инициализаций схавают это за милую душу - будут конструктор вызывать, никуда не денутся. Конструктор лучше делать inline а ещё лучше constexpr, хотя при константной инициализации он и так на этапе компиляции отработает.

Нужен пример конструктора?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Навскидку - захреначить конструктор:

typedef struct _Xfont { 
	uint8_t  *bitmap;     
	uint8_t  *glyph;       
	uint8_t   first;      
        uint8_t   last;       
	uint8_t   yAdvance; 

	_Xfont(uint8_t* b, uint8_t* g, uint16_t f, uint16_t l, uint8_t a) :
	bitmap(b), glyph(g), first((uint8_t)(f & 0xFF)), last((uint8_t)(l & 0xFF)), yAdvance(a)
	{
	} 
}Xfont; 

Пойнт, как правильно отметили выше - в отбрасывании ненужного. Будет ругаться - можно сделать static_cast.

З.Ы. Не компилял, просто идея.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

У известной "социальной группы" часто мысли сходятся :-)

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Насколько Вы не можете менять структуру? Вообще прикасаться нельзя или только размер и порядок полей трогать нельзя, а прикоснуться-то можно?

Спасибо за предыдущие ответы.

продолжим?

к сожалению, структуру менять нельзя никак - ее описание находится в чужой библиотеке Adafruit_GFx. Я, понятно, могу поправить локальную копию либы, что установлена в моем компе - но, очевидно, это не решение.

Подробнее о задаче - есть куча фонтов, совместимых с библиотекой Адафруит, структура которых _почти_ соответвует typedef Xfont из первого поста темы. Разница этого "почти" заключается в том, что фонты - кириллица, генерились из UTF кодировки и параметры first и last у них 16 битные. Фонты отлично подключаются к библиотеке и работают, за исключением ругани компилятора на несовместимость типов.

Хотелось бы, чтобы преобразование типа в шрифте происходило как-то "незаметно" :) Повторюсь, проблема в том, что править ни описание структуры (оно в чужой либе), ни данные фонтов (их слишком много) - по условиям задачи нельзя :)

Я не профи в классах и структурах С++, мне на моем уровне знаний кажется, что это невозможно. Но теплится надежда - вдруг что-то посоветуете? :)

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

А вот здесь не про это?

b707
Offline
Зарегистрирован: 26.05.2017

v258 пишет:

А вот здесь не про это?

ну да, почти про тоже :) . Только там сразу(выделено)

arduinec пишет:

Для русификации библиотеки Adafruit-GFX требуется:
- скачать любой из приведённых ниже (или выше) архивов;
- заменить файл glcdfont.c в Adafruit-GFX;
- добавить функцию utf8rus() в скетч;
....

а я хочу решить проблему без правок файла glcdfont.c в Adafruit-GFX;

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

Но теплится надежда - вдруг что-то посоветуете? :)

Ну есть только попробовать https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

Т.е. включить в коде (в самом верху *.ino-файла) прагму

#pragma GCC diagnostic ignored "-Wno-narrowing"

Не пробовал, чисто из справки по прагмам GCC. Если не взлетит - пробовать

#pragma GCC diagnostic warning "-Wno-narrowing"
b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Ну есть только попробовать https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

Т.е. включить в коде (в самом верху *.ino-файла) прагму

#pragma GCC diagnostic ignored "-Wno-narrowing"

спасибо, работает, только лучше выключать ворнинги не в самом верху файла, а непосредственно перед загрузкой проблемного фонта. А сразу после - включить предупреждения обратно, так как они, вообще-то, полезны:)

Вот так получилось:

#pragma GCC diagnostic ignored "-Wnarrowing"
#pragma GCC diagnostic ignored "-Woverflow"

#include "GlametrixBold12pt7b.h"

#pragma GCC diagnostic warning "-Wnarrowing"
#pragma GCC diagnostic warning "-Woverflow"

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

DIYMan пишет:

Ну есть только попробовать https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

Т.е. включить в коде (в самом верху *.ino-файла) прагму

#pragma GCC diagnostic ignored "-Wno-narrowing"

спасибо, работает, только лучше выключать ворнинги не в самом верху файла, а непосредственно перед загрузкой проблемного фонта. А сразу после - включить предупреждения обратно, так как они, вообще-то, полезны:)

Вот так получилось:

#pragma GCC diagnostic ignored "-Wnarrowing"
#pragma GCC diagnostic ignored "-Woverflow"

#include "GlametrixBold12pt7b.h"

#pragma GCC diagnostic warning "-Wnarrowing"
#pragma GCC diagnostic warning "-Woverflow"

 

Почитай про эти прагмы, там есть push и pop, чтобы удобней было этими диагностиками управлять ;) Но уже работает, как видишь ;) Просто правила хорошего тона требуют, чтобы state сохранялся, а ты включаешь варнинги, не будучи уверен, что они были включены вообще ;) Поэтому лучше:

#pragma GCC diagnostic push
//твои варнинги, которые отключаешь
#pragma GCC diagnostic pop

 

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Почитай про эти прагмы, там есть push и pop, чтобы удобней было этими диагностиками управлять ;) Но уже работает, как видишь ;) 

ага, спасибо

чем больше я узнаю про С++ - тем лучше понимаю, как мало я знаю :)))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Короче, полный и самый правильный вариант такой, тогда корректно восстановятся параметры командной строки:

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wnarrowing" 
#pragma GCC diagnostic ignored "-Woverflow" 

#include "GlametrixBold12pt7b.h"

#pragma GCC diagnostic pop

 

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Короче, полный и самый правильный вариант такой, тогда корректно восстановятся параметры командной строки:

#pragma GCC diagnostic push

#pragma GCC diagnostic ignored "-Wnarrowing" 
#pragma GCC diagnostic ignored "-Woverflow" 

#include "GlametrixBold12pt7b.h"

#pragma GCC diagnostic pop

 

да. "восстановить как было" - это самое правильное.

Спасибо.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

Спасибо.

Всегда рад ;)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

Хотелось бы, чтобы преобразование типа в шрифте происходило как-то "незаметно" :) Повторюсь, проблема в том, что править ни описание структуры (оно в чужой либе), ни данные фонтов (их слишком много) - по условиям задачи нельзя :)

Фу, ты, блин, а я что-то опять не в ту степь полез и подготовил пример как сделать свою структуру, но так, чтобы оригинальные функции, заточенные под Xfont её кушали и не давились. И только когда закончил пример, дошло, что свои структуры никуда подсовывать нельзя.

А Вам оказывается, нужно просто заткнуть пасть компилятору. Ну, не знаю, но полезьте в platforms.txt, найдите там строку с опциями компилятора (она длинная, типа вот такой

compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++14 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto

и добавьте её в хвост запрет на данный вид ругани

 -Wno-overflow -Wno-narrowing

Всё.

P.S.Пока писал, DIYMan уже про прагму написал. Так как у него (с прагмой) лучше - более аккуратно.

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Ну, не знаю, но полезьте в platforms.txt, найдите там строку с опциями компилятора и добавьте её в хвост запрет на данный вид ругани

 -Wno-overflow -Wno-narrowing

Всё.

Евгений, мне вариант DIYMan больше нравится. Выключаем предупреждения только тогда и там, где они не нужны, потом все включаем обратно. И работать будет у всех, кто возьмет этот скетч, а не только на одной конкретной машине.

Или у этого варианта есть какие-то подводные камни?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

Или у этого варианта есть какие-то подводные камни?

Нет. Я ж написал, что он лучше (не успели заметить?).

Просто мой проще и после примера (а я его честно написал), я уже с психу, не думая, "да, воткни опции, делов-то!" :-)

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Просто мой проще и после примера (а я его честно написал), я уже с психу, не думая, "да, воткни опции, делов-то!" :-)

а пример стерли уже? А то выкладывайте, чего ему пропадать зря. Я учиться люблю :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, пожалуйста:

#include <Printing.h>

// Оригинальная Xfont
typedef struct { 
	uint8_t  *bitmap;     
	uint8_t  *glyph;       
	uint8_t   first;      
   uint8_t   last;       
	uint8_t   yAdvance;  
} Xfont; 

//
// Три функции, принимающией параметром ОРИГИНАЛЬНУЮ Xfont 
//	(они типа в библиотеке спрятаны)
void kaka1(const Xfont * a) { printVar(a -> first); }
void kaka2(const Xfont & a) { printVar(a.first); }
void kaka3(const Xfont a) { printVar(a.first); }

//
// Новая структура
//	нужно включить С++14 или С++17 в platforms.txt для constexpr конструктора
//
struct myFont : public Xfont {
	constexpr myFont(uint8_t  *bmp, uint8_t  *glp, uint16_t  f, uint16_t  l, uint8_t  yAdv) {
		bitmap = bmp;
		glyph = glp;
		first = f & 0xFF;
		last = l & 0xFF;
		yAdvance = yAdv;
	}
};

// Объявляемся с новой структурой
const Xfont GG_rus PROGMEM = { nullptr, nullptr, 0x0410, 0x044F, 25 };

void setup(void) {
	Serial.begin (57600);
	//
	// Эти функции преспокойно кушают нашу новую структуру, ибо полиморфизм!
	//
	kaka1(& GG_rus);
	kaka2(GG_rus);
	kaka3(GG_rus);
}

void loop(void) {}
b707
Offline
Зарегистрирован: 26.05.2017

круто, на самом деле на что-то подобное я и надеялся, только мои попытки найти что-то похоже в гугле ничего не дали.

Если честно, пока не понимаю, подойдет мне это или нет. Но я попытаюсь разобраться.

Спасибо.