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

 
 
6 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> Стиль программирования на Си, описание функции
sensor_ua
сообщение Apr 1 2008, 08:17
Сообщение #31


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Но это, повторяю, другое

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

для начала вменяемые компиляторы не будут ругаться на передачу в качестве фактического параметра функции const переменной, когда формальный параметр объявлен не const. В "прямоугольных" вариантах применения (таких как Вы показали) действительно интеллект компилятора может быть на высоте.
Цитата
Думается, что написать ключевое слово 'static' не является слишком обременительным.

Вы не поверитеwink.gif - использую описанные Вами приёмы и не стесняюсь
Цитата
И в чем они состоят?

Насчёт одинаково хорошо
http://www.klen.org/Projects/Embeded-gnu-t...last_build.html
http://www.klen.org/Projects/Embeded-gnu-t...gcc-cpp-how.txt
А насчёт нюансов использования, например, смотрим пост 7
http://electronix.ru/forum/index.php?showt...;p=247899&#
Не то, чтобы я против использования плюсов - этим нужно заниматься(С)
Но как раз реализации "плюсовости" у компиляторов гораздо более различны, нежели отклонения в работе их препроцессоров.


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 1 2008, 09:28
Сообщение #32


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(sensor_ua @ Apr 1 2008, 15:17) *
Дальше бессмысленно обсуждать - лучше/хуже, видно/невидно и применять/не применять, рекомендуется/нерекомендуется суть разные вещи.

Не следует путать приятное с полезным. В одном случае имеем объективные трудности из-за использования низкоуровневого кодирования, которое требует повышенного внимания - это сродни кодированию на ассеблере, за всем надо внимательно следить. Обратная сторона этого - высокая эффективность (малый размер, быстродействие) кода. В другом случае сами себе раскладываем грабли. Которые можно обойти, используя более адекватные средства, получив результат не хуже. Каждый случай использования препроцессора должен быть четко обоснован, и на основании этого сделан вывод, что иные пути дают худший результат или вообще не дают такового.

Цитата(sensor_ua @ Apr 1 2008, 15:17) *
для начала вменяемые компиляторы не будут ругаться на передачу в качестве фактического параметра функции const переменной, когда формальный параметр объявлен не const.


Вы про это:

Код
const int a = 10;
int b;

int g(int x, int y);

int main()
{
    g(a, b);
}


?

Если да, то вот результат:

Код
int main()
        main:
{
    g(a, b);
....               LDI     R30, LOW(b)
....               LDI     R31, (b) >> 8
8120               LD      R18, Z
8131               LDD     R19, Z+1
E00A               LDI     R16, 10
E010               LDI     R17, 0
........           CALL    ??g
}


Никакой ругани нет. И это не странно, если подумать и понять, что компилятор вполне адекватно оценивает ситуацию и не видит ничего опасного в таком вызове функции. Да и что тут может быть опасного? Ведь передача аргумента делается по значению. Вот если бы была попытка передать указатель (или ссылку) на константный объект, то это была бы ошибка, т.к. такая ситуация может привести к попытке изменить констатный объект внутри вызываемой функции. Но компилятор этого и не разрешает. А если какой-то компилятор разрешает, то это просто его баг и ничего более. Все эти правила стандартизованы и исходят из здравого смысла.

Что не так?

Цитата(sensor_ua @ Apr 1 2008, 15:17) *
В "прямоугольных" вариантах применения (таких как Вы показали) действительно интеллект компилятора может быть на высоте.

Хорошо, покажите свои "треугольные" или "круглые" варианты, где в подобной ситуации (с константами) компилятор облажается. Давайте пример в студию, посмотрим его. Интересно.

Цитата(sensor_ua @ Apr 1 2008, 15:17) *
Вы не поверитеwink.gif - использую описанные Вами приёмы и не стесняюсь

Тогда не понятно, какую точку зрения отстаиваете.

Цитата(sensor_ua @ Apr 1 2008, 15:17) *

И что конкретно там не так? Я никакого криминала не увидел. Особенно, в части константных объектов - там вообще ни слова не нашел про это. Может, плохо искал? smile.gif

Цитата(sensor_ua @ Apr 1 2008, 15:17) *
А насчёт нюансов использования, например, смотрим пост 7
http://electronix.ru/forum/index.php?showt...=247899�

И что? Манглинг имен - обычное дело в С++, жить реально не мешает. И опять совсем не понял, как это мешает использовать константные объекты вместо макросов?

Цитата(sensor_ua @ Apr 1 2008, 15:17) *
Но как раз реализации "плюсовости" у компиляторов гораздо более различны, нежели отклонения в работе их препроцессоров.

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


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 1 2008, 12:40
Сообщение #33


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Lem @ Mar 31 2008, 22:08) *
как во что разворачивается макроопределение выяснить практически нереально (достоверно)

Как правило препроцессор идёт отдельным исполняемым файлом и/или у компилятора есть соответствующий ключик "выполнить только препроцессор".
И можно получить выход препроцессора и всё поразглядывать.



Да, очень много чего можно затолкать в enum-ы, inline-функции и т.п.
Да, в С++ есть ссылки, позволяющие уменьшить использование указателей и связанных с неправильным их применением ошибок (ударение на слове "неправильным", а не на слове "применением"). И т.д. и т.п.
Но, извините,
#define TRUE FALSE
и
#define SQR(x) x * x
это примеры вредительского и безграмотного применения макросов, а не их генетической ущербности.
Но на их базе строится рекомендация "использование макросов следует уменьшать в идеале до нуля", что, на мой взгляд, неправильно, как неправильны и рекомендации не использовать указатели (а почему тогда в стандарте оставили не только условную компиляцию, но и функциональные макросы, склейку и подстановку аргументов и оставили указатели?)

Так же как и с goto, который я использую редко и на форумах иногда сам привожу примеры, как можно обойтись без goto и при этом и сгенерированный код не растёт, и читаемость улучшается, но который я инода таки использую - так же и с макросами:
Используйте, не бездумно, голова дана именно для выбора нужного средства языка!
(Кстати, а какое средство языка можно использовать бездумно? Знаменитые примеры "индусского" кода написаны и без макросов, и без gotoи часто вообще на яве, изначально "лишённой недостатков С/С++")
Правильно и в нужном месте применённые макросы, на мой взгляд, только улучшают (не слишком хорошо формализуемый и очень вкусовой параметр) читаемость кода. Кончено, для людей, умеющих с ними обращаться (та же проблема с указателями).
Огрызок .h
Код
typedef WINAPI void (*DlPortWritePortUchar_t) (unsigned port, uint8_t d);
typedef WINAPI uint8_t (*DlPortReadPortUchar_t) (unsigned port);
typedef WINAPI void (*DlPortWritePortBufferUchar_t) (unsigned port, const uint8_t *pd, int len);

class lpt_dlportio_t : public lpt_io_t
{
public:
    lpt_dlportio_t(unsigned _base);
    ~lpt_dlportio_t();

    virtual uint8_t read(rd_offset offs);
    virtual void write(wr_offset offs, uint8_t d);
    virtual void write_data(const uint8_t *pd, int len);

private:
    HINSTANCE hdlportio;
#define _DL_PTR(_f_) _f_##_t _f_##_P
    _DL_PTR(DlPortWritePortUchar);
    _DL_PTR(DlPortReadPortUchar);
    _DL_PTR(DlPortWritePortBufferUchar);
#undef  _DL_PTR
}; // class lpt_dlportio_t


Огрызок .cpp
Код
lpt_dlportio_t::lpt_dlportio_t(unsigned _base)
    : lpt_io_t(_base), hdlportio(NULL)
{
    hdlportio = LoadLibrary("DLportIO.dll");
    if (hdlportio == NULL)
        throw error_win32_t(E_INVHARD, "Can't load port access library `DLportIO.dll'");

#define _DL_LOAD(_f_)\
        do {\
            _f_##_P = (_f_##_t)GetProcAddress(hdlportio, #_f_);\
            if(_f_##_P == NULL)\
                throw error_win32_t(E_INVHARD, "Can't load port access library `DLportIO.dll'"); \
        } while(0)

    _DL_LOAD(DlPortWritePortUchar);
    _DL_LOAD(DlPortReadPortUchar);
    _DL_LOAD(DlPortWritePortBufferUchar);
#undef _DL_LOAD

} // lpt_dlportio_t::lpt_dlportio_t


И не говорите мне, что этот текст надо переписать без макросов для облегчения чтения и сопровождения (представим себе, что понадобилось добавить ещё одну функцию из dlportio.dll и/или изменить обработку ошибки - в каком случае надо больше до-/пере-писывать руками и где при этом больше шансов ошибиться в одной из ветвей - в варианте с макросами или с прямым текстом?

И ещё пример на эту тему

http://www.telesys.ru/wwwboards/mcontrol/1...es/314290.shtml


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 1 2008, 12:48
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



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

В связи с этим вопрос. Как в IAR просмотреть результаты работы препроцессора. Например где можно увидеть результаты вычисления констант? В ряде случаев это реально помогло бы. smile.gif
Go to the top of the page
 
+Quote Post
Lem
сообщение Apr 1 2008, 13:07
Сообщение #35


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 20-03-05
Пользователь №: 3 533



одним из авторитетов для меня является Герб Саттер,ну, там ещё куча умных опытных людей, которые много поработали с БОЛЬШИМИ системами и знают, какова цена тех или иных ошибок при отладке и сопровождении проектов, создаваемых коллективами за длительные сроки и большие деньги
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 1 2008, 13:11
Сообщение #36


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(SasaVitebsk @ Apr 1 2008, 19:48) *
На данном этапе не планирую отказываться от этого средства языка. Возможно потом пересмотрю данное решение.

Да никто и не призывает отказываться от препроцессора и макросов - это просто нереально, т.к. не существует адекватной замены всем средствам и во всех ситуациях. Речь о том, что надо стремиться свести к минимуму его (препроцессора) использование и использовать по возможности только такие варианты, которые не несут подводных граблей. Во всяком случае крайне желательно исключить повсеместное использование макросов препроцессора в качестве литералов и функций.

Цитата(SasaVitebsk @ Apr 1 2008, 19:48) *
В связи с этим вопрос. Как в IAR просмотреть результаты работы препроцессора. Например где можно увидеть результаты вычисления констант? В ряде случаев это реально помогло бы. smile.gif

Да, такое средство очень кстати и меня не раз выручало. Ключик:

Код
--preprocess=[c][n][l] file|directory
                Preprocessor output
                   c     Include comments
                   n     Preprocess only
                   l     Include #line directives


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 1 2008, 13:15
Сообщение #37


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SasaVitebsk @ Apr 1 2008, 15:48) *
Как в IAR просмотреть результаты работы препроцессора. Например где можно увидеть результаты вычисления констант? В ряде случаев это реально помогло бы. smile.gif
Project->Options->C/C++ compiler->Preprocessor-> галочка Preprocessor output to file. Только результатов вычисления там не будет - вычисляет компилятор в процессе оптимизации. Можно завести глобальную переменную и присвоить ей значение макроса, а дальше смотреть в листинге какое значение в эту переменную заносится.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Apr 1 2008, 13:37
Сообщение #38


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Не следует путать приятное с полезным...

Не знаю о чём Вы, но я о том, что заявления, что что-то НЕ РЕКОМЕНДУЕТСЯ, стОит подкреплять не столько личным мнением/опытом (нисколько не умаляю Ваших достоинств), сколько какими либо ссылками на Стандарт.

Цитата
Тогда не понятно, какую точку зрения отстаиваете

Я считаю, что препроцессор - нужный и полезный инструмент. Да, огульное его применение не приветствуется, так как существует много описанных выше причин, по которым возникают ошибки. Я для супа использую ложку, а для бифштекса - нож и вилку. Я могу объяснить, почему вилкой есть суп не получится, но мне трудно объяснять ребёнку, почему нельзя есть бифштекс ложкой.
typedef и применение текстовых замен действительно очень похожи, и если нужен тип, то typedef предпочтительнее, чем текстовая подстановка, но ведь не просто так - они отличаются - свойства у typedef имеются, которых у текстовых подстановок нет. Препроцессор позволяет манипулировать с именами (склейка, подмена, удаление, индексация), что при отсутствии поддержки шаблонов на уровне самого языка является необходимым дополнением. Что касается сложных выражений, то применение препроцессора ограничено его ограниченными возможностями и он действительно не предупреждает о переполнениях и прочих глупостях. Но сложность бывает разная - где мы в уме считаем, где не прочь в столбик, а где и калькулятора не хватает. Потому рекомендации по отказу от применения препроцессора при любой возможности считаю необоснованными.
Цитата
Хорошо, покажите свои "треугольные" или "круглые" варианты, где в подобной ситуации (с константами) компилятор облажается. Давайте пример в студию, посмотрим его. Интересно.

Что касается константных объектов приведу пример, который говорит в пользу препроцессора как удобного инструмента
Это выдаёт ошибку в IAR
Код
typedef void (MY_FOO_TYPE)();
typedef struct {
  int a;
  int b;
  int c;
  MY_FOO_TYPE * foo;
} mytype;

void myfoo1(void);
void myfoo2(void);
#define sDefault_Value1 {   \
                       777, \
                         0, \
                        55, \
                    &myfoo1 \
}
#define sDefault_Value2 {   \
                       111, \
                       222, \
                      3333, \
                    &myfoo2 \
}


const int def1_aa = 777;
const int def1_bb = 0;
const int def1_cc = 55;
const MY_FOO_TYPE * def1_foo = &myfoo1;

mytype a = {0};

const mytype aaa = sDefault_Value1;
const mytype bbb = sDefault_Value2;
volatile int i;
int main(void){
  while(1){
    if(i == a.a){
      i = a.b;
      a = aaa; // ошибки нет
      a.a = def1_aa;
      a.b = def1_bb;
      a.c = def1_cc;
          a.foo = def1_foo;//!!!ошибка
//Error[Pe513]: a value of type "void () const *" cannot be assigned to an entity of type "void () *" D:\avrtst\avrtst\main.c 44

    }
    else{
      i = a.a;
      a = bbb;
    }

  }
  return 0;
}

void myfoo1(void){
;
}

Наверно правильно выдаёт

Цитата
А вот на препроцессор стандарта нет

п.6.10
http://upload.caxapa.ru/standards/ansi_c-i...c_9899-1999.pdf

Цитата
Да, такое средство очень кстати и меня не раз выручало. Ключик:

Отдельное спасибо


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 1 2008, 13:40
Сообщение #39


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(dxp @ Apr 1 2008, 15:11) *
Во всяком случае крайне желательно исключить повсеместное использование макросов препроцессора в качестве литералов и функций.
Ну в такой формулировке - с указанием где именно и без абсолютной категоричности - можно согласиться :-)
Но ведь обычно идёт разговор "запретить и всё тут, так как это источник ошибок".
Так человек, не разобравшийся в понятиях "побочный эффект" и "точка следования" рано или поздно накосячит с применением операторов ++, -- и ещё найдёт где. Но ведь никто не рекомендует отказаться от них и начать писать p = p + 1; Или уже рекомендуют? wink.gif


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 1 2008, 13:50
Сообщение #40


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(ReAl @ Apr 1 2008, 19:40) *
Как правило препроцессор идёт отдельным исполняемым файлом и/или у компилятора есть соответствующий ключик "выполнить только препроцессор".

Это где такое правило? В GCC? Рад за него. В IAR с некоторых пор появился ключик. А вот в используемом мной сейчас VDSP такого удовольствия нет (не нашел). Т.ч. тут как повезет.

Цитата(ReAl @ Apr 1 2008, 19:40) *
Да, очень много чего можно затолкать в enum-ы, inline-функции и т.п.

Именно! smile.gif И все, что можно туда затолкать, не надо пихать в макросы. Об этом и спич.

Цитата(ReAl @ Apr 1 2008, 19:40) *
Но, извините,
#define TRUE FALSE

Да это я вообще в качестве хохмы привел, не апеллируя к этому примеру, как к аргументу. Просто этот пример наглядно демонстрирует мощь препроцессора как дестуктивного средства, только и всего.

Цитата(ReAl @ Apr 1 2008, 19:40) *
это примеры вредительского и безграмотного применения макросов, а не их генетической ущербности.

Как насчет вышеприведенного примера про

Код
#define I 7
#define N 2
#define C 0

?

А ведь это не лохи какие-то делали, а вполне серьезная и уважаемая фирма IAR Systems, которая выпускает очень достойные продукты. Замечательные грабли. Замечательный пример той же самой деструктивной мощи. Да, препроцессор обладает известной гибкостью в силу своих свойств по текстовой подстановке, но это палка о двух концах. Не стоит злоупотрелять ею.

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

Цитата(ReAl @ Apr 1 2008, 19:40) *
Но на их базе строится рекомендация "использование макросов следует уменьшать в идеале до нуля",

Да. Но идеал недостижим. Поэтому препроцессор останется.

Цитата(ReAl @ Apr 1 2008, 19:40) *
(а почему тогда в стандарте оставили не только условную компиляцию,

Потому, что для нее нет адекватной замены.

Цитата(ReAl @ Apr 1 2008, 19:40) *
но и функциональные макросы, склейку и подстановку аргументов

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

Цитата(ReAl @ Apr 1 2008, 19:40) *
и оставили указатели?)

Указатели из другой оперы, не надо все в кучу валить. Еще спроси (ехидно так), зачем оставили ассемблер - там тоже можно при невнимательном обращении наворотить. smile.gif


Цитата(ReAl @ Apr 1 2008, 19:40) *
Так же как и с goto, который я использую редко

Реально есть одна ситуация, где без него геморно - выход из вложенного цикла. Вроде все, больше не знаю (навскидку). Из-за этого оный оператор и оставили в языке.

Цитата(ReAl @ Apr 1 2008, 19:40) *
так же и с макросами:
Используйте, не бездумно, голова дана именно для выбора нужного средства языка!

Осталось найти, как добраться до головы иаровских разрабов, соорудивших макросы, приведенные выше. smile.gif Если есть возможность разложить грабли - они будут разложены. Раньше или позже, чаще или реже. Желательно, чтобы это было реже. Для этого использование препроцессора надо свести к минимуму, о чем только и речь. Никто не призывает отказаться от него вообще - это, повторяю, нереально. Чего в крайности кидаться.

Цитата(ReAl @ Apr 1 2008, 19:40) *
(Кстати, а какое средство языка можно использовать бездумно? Знаменитые примеры "индусского" кода написаны и без макросов, и без gotoи часто вообще на яве, изначально "лишённой недостатков С/С++")

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

Цитата(ReAl @ Apr 1 2008, 19:40) *
И не говорите мне, что этот текст надо переписать без макросов для облегчения чтения и сопровождения (представим себе, что понадобилось добавить ещё одну функцию из dlportio.dll и/или изменить обработку ошибки - в каком случае надо больше до-/пере-писывать руками и где при этом больше шансов ошибиться в одной из ветвей - в варианте с макросами или с прямым текстом?

Это большой вопрос, как лучше, пример не убеждает. Насчет руками - про рефакторинг слышал? Кроме того, тут пример очень осторожного использования - определение макроса лежит прямо тут же, все перед глазами. Но не дай бог кто-нить вздумает использовать такое же имя _DL_PTR в своей программе. Будет удивлен. smile.gif Т.ч. тут тоже есть, что обсудить.

Цитата(ReAl @ Apr 1 2008, 20:40) *
Ну в такой формулировке - с указанием где именно и без абсолютной категоричности - можно согласиться :-)
Но ведь обычно идёт разговор "запретить и всё тут, так как это источник ошибок".

Это где это сказано, что "запретить" и все тут? Сказано было, свести к минимуму.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 1 2008, 14:43
Сообщение #41


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(dxp @ Apr 1 2008, 16:50) *
Осталось найти, как добраться до головы иаровских разрабов, соорудивших макросы, приведенные выше. smile.gif
Да фиг с ними, с разработчиками. Ну достучишься, и "миллионы строк кода уже написанного, отлаженного и работающего кода сразу перестанут компилироваться" wink.gif
Код
#ifdef I
#undef I
#endif
#ifdef N
#undef N
#endif
#ifdef C
#undef C
#endif
Добавлять сразу после #include <ioavr.h>
Кстати, эти же грабельки перекочевали и в заголовочники avr-libc.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Apr 1 2008, 14:51
Сообщение #42


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(dxp @ Apr 1 2008, 15:50) *
Это где такое правило? В GCC? Рад за него.
Во-первых, "как правило" != "существует правило", во вторых, из правил есть исключения.
Необходимость выдавать ассемблерный листинг тоже нигде не прописана, но как правило эта возможность имеется.
На моей памяти большинство компиляторов позволяли просмотреть выдачу препроцессора.

Цитата(dxp @ Apr 1 2008, 15:50) *
Как насчет вышеприведенного примера про
Код
#define I 7
#define N 2
#define C 0

Ну что я скажу... У gcc в этом месте SREG_I, SREG_N и так далее.
Солидная фирма, не солидная - а бывает и на старушку прорушка.


Цитата(dxp @ Apr 1 2008, 15:50) *
Потому, что для нее нет адекватной замены.
Я спросил не "почему условную компиляцют оставили", а "почему вместе с ней оставили функциональные макросы, склейку, ..."

Цитата(dxp @ Apr 1 2008, 15:50) *
Совместимость и преемственность. Попробуй убери что-нить из этого - миллионы строк кода уже написанного, отлаженного и работающего кода сразу перестанут компилироваться.
Какого кода??? С++ ?
А какого лешего компилировать С-код С++-компилятором?
Или тогда решили, что всё, С-компиляторы больше никто не будет писать и даже развивать, и поэтому для сопровождения С-кода надо в С++ оставить явно вредные вещи? Могли бы в С++ режиме и устранить "огромный недостаток". Тем более, что в мелких, неочевидных и местами обидных случаях С++ таки сильно отличается от С (например, литерал 'я' в языке С имеет тип int а в С++ имеет тип char).


Цитата(dxp @ Apr 1 2008, 15:50) *
Указатели из другой оперы, не надо все в кучу валить. Еще спроси (ехидно так), зачем оставили ассемблер - там тоже можно при невнимательном обращении наворотить. smile.gif
А где ассемблер в стандарте языков С/С++ ??? laughing.gif


Цитата(dxp @ Apr 1 2008, 15:50) *
Для этого использование препроцессора надо свести к минимуму, о чем только и речь. Никто не призывает отказаться от него вообще - это, повторяю, нереально. Чего в крайности кидаться.
Коренное отличие многих среств языка от средств препроцессора в том, что с ними код читается без подводных граблей. Сразу видно, как используется средство, сразу понятно, что тут можно ожидать. А вот с препроцессором оно несколько не так.
Так в том-то и дело, что агитаторы за предельную минимизацию применения указателей а то иногда и тернарной операции говорят то же самое - "неочевидно, непонятно, в отличие от массивов, ссылок и if/else". И часто при этом столь же категоричны, как и в случае с goto - "не должно быть вообще", "по нашему стандарту предприятия goto запрещены". Так что кидаюсь в крайности не я.


Цитата(dxp @ Apr 1 2008, 15:50) *
Это большой вопрос, как лучше, пример не убеждает. Насчет руками - про рефакторинг слышал?
Это как - я добавляю в описание класса поле, а в конструкторе сразу по кнопочке "сделайте мне красвиво" сгенерируется для него
Код
нужное_имя = (нужный_тип)GetProcAddress(hdlportio, нужная_строка);
            if(нужное_имя == NULL)
                throw error_win32_t(E_INVHARD, "Can't load port access library `DLportIO.dll'");
Или всё же придётся ручками это делать?


Цитата(dxp @ Apr 1 2008, 15:50) *
Кроме того, тут пример очень осторожного использования - определение макроса лежит прямо тут же, все перед глазами. Но не дай бог кто-нить вздумает использовать такое же имя _DL_PTR в своей программе. Будет удивлен. smile.gif Т.ч. тут тоже есть, что обсудить.
Получит предупреждение о переопределении и сразу увидит что и где конфликтует.
Если код пишет так, что предупреждения валят десятками на каждый файл и поэтому отключил без разбору все предупреждения - то не помогут никакие ограничения - наксоячит.

Цитата(dxp @ Apr 1 2008, 15:50) *
Это где это сказано, что "запретить" и все тут? Сказано было, свести к минимуму.
Ну, ты не самый бескомпромиссный борец с препроцессором :-) И то считаешь, что "в идеале исключить вообще".
Я же считаю, что "в идеале" его может и неплохо бы заменить чем-то более грамотным, но оно почти наверняка будет более сложным и менее удобным (эти два фактора могут не уменьшить глюкодромистость, а увеличить), поэтому пусть лучше остаётся как есть и как с любым инструментом - его нужно знать, чтобы пользоваться правильно. А для этого нужно пользоваться. А чтобы было меньше отрезанных пальцев - не убирать с кухни ножи, а учиться ими пользоваться тогда, кода это надо и не махать ими, показывая, как летали листья. Но не говорить, что есть открывашки, консервные ножи и хлеб можно купить уже нарезанным, поэтому применение ножей
Цитата(dxp @ Mar 31 2008, 14:16) *
нужно свести к минимуму, в идеале исключить вообще. Но на практике это не удается сделать, поэтому приходится жить с ним. По большому счету ... имеет смысл использовать только
в затупленном виде для простеньких вещей типа намазывания масла.
Просто нужно учить тому, что каждый инструмент нужно использовать с умом. А не рекомендовать "минимизировать до отсутствия", так как пока научитесь - можете пораниться. А уж сколько людей ими убито... rolleyes.gif


Цитата(Сергей Борщ @ Apr 1 2008, 16:43) *
Кстати, эти же грабельки перекочевали и в заголовочники avr-libc.
Разве? Там ведь в common.h сидят SREG_*
Хотя, мне кажется, желание "облегчить переход с IAR" у них инода избыточное, могли и добавить односимвольные.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Apr 1 2008, 20:44
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(dxp @ Apr 1 2008, 16:50) *
А вот в используемом мной сейчас VDSP такого удовольствия нет (не нашел). Т.ч. тут как повезет.

Самостоятельные препроцессоры "C" не редкость, да и тем-же GCC прогнать можно... Посему на везение уповать совсем незачем smile.gif.


Цитата(ReAl @ Apr 1 2008, 17:51) *
А какого лешего компилировать С-код С++-компилятором?

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


Цитата(ReAl @ Apr 1 2008, 16:40) *
Но ведь никто не рекомендует отказаться от них и начать писать p = p + 1; Или уже рекомендуют? wink.gif

Рекомендуют smile.gif С полгода назад на форуме проскаивала ссылка на переводную статью по "правильному стилю" именно с такой рекомендацией. У многих сей опус вызвал одобрение smile.gif. Я естественно, не мог смолчать - возражал...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Apr 1 2008, 22:17
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Apr 2 2008, 00:44) *
Рекомендуют smile.gif

smile.gif А мне так понравилось. По сравнению с Паскалем, к примеру. smile.gif

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

Всётаки выбор - великое дело. Зачем самих себя ограничивать изначально. Сталкиваешься с граблями (своими), анализируешь, применяешь так, чтобы в дальнейшем не наступать. Так свой подход вырабатывается. А написание прог для совместного использования, или для постороннего использования, - всётаки сложная задача требующая своих подходов. Я, чаще всего, заимствованное переписываю под себя.

Тем не менее, с учётом данной дискуссии, сделаю выводы и обдумаю все ваши предложения. Попробую переосмыслить. А то действительно проблемы некоторые уже возникали. А всётаки было бы неплохо иметь элемент языка, который бы определял константы под которые гарантированно не выделяется память и которые вычисляются строго на этапе компиляции. Для IBM, экономия памяти не стоит как задача, а вот для мелкоAVRов былобы неплохо.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 2 2008, 06:58
Сообщение #45


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(SasaVitebsk @ Apr 2 2008, 01:17) *
По сравнению с Паскалем, к примеру. smile.gif


Анафема тому Паскалю, который не поддерживает функции inc(N,M), dec(N,M) smile.gif
А насчет пред/пост инкремента, например, действительно генератор граблей. Но пользоваться приятно... до тех пор, пока есть уверенность в адекватной трансляции.
Go to the top of the page
 
+Quote Post

6 страниц V  < 1 2 3 4 5 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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