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, но хотелось чего-то более переносимого.

★★★

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

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

stopitplease ()

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

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

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

E ★★★ ()

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

legolegs ★★★★★ ()

Как можно заставить компилятор для определённого куска кода (или инклуда) считать, что здесь 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 ★★★★★ ()
Ответ на: комментарий от MKuznetsov

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

E ★★★ ()
Ответ на: комментарий от 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 ★★★★★ ()
Ответ на: комментарий от DesertFox

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

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

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

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

Вопрос был:

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

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

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

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

Компилятор и линковщик - это немного разные программы.

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

И что?

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

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

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

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

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

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

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

NeXTSTEP ()

В C то-же давно можно const char *

quest ★★★★ ()

Попробуйте extern «C» { static char * icon_xpm [] = { "..", "..", ... }; }.

anonymous ()
Ответ на: комментарий от 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 ★★★★★ ()

а что мешает написать:

const
#include "file.xpm"
или я чего-то не понимаю?

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

Лучший ответ. Спасибо :) Я даже не подумал о таком.

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

Грязноватый вариант. Не забудь написать комментарий, а не то тебя сожрут велоцирапторы

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

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

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

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

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

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

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

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

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

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