LINUX.ORG.RU

Объявление char * констант в C++

 ,


0

3

Обычно XPM-изображения в программу встраиваю с помощью #include "icon.xpm". Проблема в том, что по стандарту XPM - это static char * icon_xpm [] = { "..", "..", ... };. Это прокатывает в C, но в C++ инициализация char * константной строкой - это deprecated и он требует const char *. Править руками/sed/awk каждую иконку - не вариант.

Как можно заставить компилятор для определённого куска кода (или инклуда) считать, что здесь C и действуют его правила? Нагуглилось решение только с прагмами для gcc, но хотелось чего-то более переносимого.

★★★

Последнее исправление: E (всего исправлений: 1)

Сишку юзай, делов то.

Deleted
()

Править руками каждую иконку можно, но неудобно

Внезапно, есть sed. Тебе всего-то сменить char* на const char*, так ведь?

stopitplease
()

Делай нормально. На поставленную тобой задачу можно смело ответить - юзай sed/perl/awk/etc.

false ★★★★★
()
Ответ на: комментарий от false

Задача вообще не в том. Юзать sed - это и есть «править руками», это костыльное решение. Новые созданные иконки будут объявлены как static char * - стандарт такой. Некоторые просмотрщики или библиотеки вообще не примут такой XPM, уже была ситуация.

E ★★★
() автор топика

Как можно заставить компилятор для определённого куска кода (или инклуда) считать, что здесь C и действуют его правила? Нагуглилось решение только с прагмами для gcc, но хотелось чего-то более переносимого.

увы. Говнокод надо костылять везде по разному. Char* ДОЛЖНА быть константой, тупо потому, что она константа. А если у тебя она не константа, то ты говнокодер.

Да, для MSVC тоже есть прагма. Ну и для всяких других тоже.

emulek
()
Ответ на: комментарий от E

Новые созданные иконки будут объявлены как static char * - стандарт такой.

дерьмовый стандарт, в котором UB.

Некоторые просмотрщики или библиотеки вообще не примут такой XPM, уже была ситуация.

их тоже надо либо закопать, либо исправить.

emulek
()
Ответ на: комментарий от crowbar

define char const char

кстати вариант и undef сразу после include, хотя правильнее просто использовать опции компилятора (-Wno-write-strings для gcc/clang)

П.С. XPM в 2014-м? o_O

wota ★★
()

Я не понял, в чём проблема-то? Это же просто warning. Или ты с -Werror собираешься и это нельзя поменять?

Напиши кросс-компиляторную прагму на дефайнах, делов-то.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от wota

XPM в 2014-м

Отличное, кстати, решение для хранения мелких изображений в VCS. И встраивать легко. Сабж был единственным косяком.

E ★★★
() автор топика
Ответ на: комментарий от E

Отличное, кстати, решение для хранения мелких изображений в VCS

во-первых оно не умеет alpha-канал, во-вторых такие изображения будут выглядеть плохо или слишком мелко на экранах с высоким dpi, тот же svg тоже в текстовом формате, но лишен указанных выше недостатков

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от wota

оно не умеет alpha-канал

Для мелких картинок хватит прозрачного цвета. А вообще умеет с надстройками.

такие изображения будут выглядеть плохо или слишком мелко на экранах с высоким dpi

Пиксельную графику ещё никто не отменял :)

E ★★★
() автор топика
Ответ на: комментарий от E

Пиксельную графику ещё никто не отменял :)

понемногу она уходит, линуксовые иконки уже в основном в svg, на маке тоже все больше векторные или пиксельные, но большого размера, про венду не в курсе

wota ★★
()
Ответ на: комментарий от E

Видимо, так и придётся делать, раз других решений нет. Спасибо.

в Makefile прописать правило .o.xpm с обычным gcc(не++) и не линковать ресурсы как static. Или .c.xpm и добавить в него строчку с вызовом sed

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

XPM-данные - это статическая переменная, извне она будет не видна никак, поэтому каждый xpm превращать в объектный файл бесполезно, их нужно включать в source-файл, где они использоваться будут.

E ★★★
() автор топика
Ответ на: комментарий от E

Вопрос был:

Как можно заставить компилятор для определённого куска кода (или инклуда) считать, что здесь C и действуют его правила?

Это работает только для линковщика, здесь не тот случай.

А что не сработало? Какой результат ты ожидал и что не вышло?

DesertFox
()
Ответ на: комментарий от E

И что?

Чего вы хотели добиться?

Код в extern C будет интерпретирован, как C код. Разве не то что вы хотели?

DesertFox
()
Ответ на: комментарий от legolegs

Научи свою билдсистему делать из .xpm какой-нибудь .cppxpm и инклудь его.

Вот это плюсую.

В случае Makefile, сделай правило

%.cppxpm: %.xpm
	sed "s/char/const char/" "$<" > "$@"

NeXTSTEP ★★
()
Ответ на: комментарий от anonymous

А еще лучше включить заголовочный файл, окружив той же директивой extern.

anonymous
()
Ответ на: комментарий от anonymous
$ ./run.sh
+ cat ./run.sh
#!/bin/bash -x

cat $0
g++ -x c++ $i - <<EOF
extern "C" {
  static char * icon_xpm [] = {
    "..", "..", "..." };
}
main(){}
EOF
+ g++ -x c++ -
<stdin>:3:23: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
<stdin>:3:23: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
<stdin>:3:23: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
anonymous
()

1) xpm в 2014? Это типа, традиционные евразийские ценности заставляют ЭТО использовать чтоли, или что?

2) include ресурсов, напр. картинок, в код? Вообще, бить за такое по рукам надо.

lovesan ★★
()
Ответ на: комментарий от legolegs

я к тому что можно изменить генератор xpm, добавить опцию для этого например

quest ★★★★
()

Может лучше обернуть всё в функции

images.h:

#ifndef IMAGES_H
#define IMAGES_H

#ifdef __cplusplus
extern "C" {
#endif

const char * const * getGreenSimpleCrestXpm();

#ifdef __cplusplus
}
#endif

#endif // IMAGES_H

images.c

#include "images.h"

#include "green_simple_crest.xpm"

const char * const * getGreenSimpleCrestXpm()
{
	return (const char * const *)green_simple_crest_xpm;
};

AlexVR ★★★★★
()
Ответ на: комментарий от E

Вот ты сам выше говорил

XPM-данные - это статическая переменная, извне она будет не видна никак, поэтому каждый xpm превращать в объектный файл бесполезно, их нужно включать в source-файл, где они использоваться будут.

Я ещё выделю, что в XPM лежит Си код. ==> Собирать все XPM данные надо в исходнике на Си, где они будут преобразовываться в нужный формат. А тут и начинаются варианты: или преобразуешь в C++ класс или Си-структуру.

Со вторым всё проще, написал прямо на Си функции инициализации (преобразования всех изображений из XPM-данных) и используй [1]

Вариантов с С++ больше, но все их надо сводить к преобразованию типов: через define [2] или функции обёртки. (см. выше)

Использование функций - более красивый и рекомендуемый способ. Это даёт возможность дальнейшего расширения и использования графических тем в программе. А вот использовать ли для каждой иконки свою функцию или функцию от enum - решать тебе.

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

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

E ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.