Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Препроцессор. Или inline ф-ция как макрос. Прототип inline ф-ции с возвратом значен 
V
    Опции темы
andrew_121
Дата 8.6.2008, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



День добрый.

Нужно стандартные ф-ции, типа:
Код

strcpy
strcat
strcmp
...

Реализовать в виде макроса. Сама реализация понятна, но как вернуть значение ?

Код

#define strcmp(dst, src) { \
    if ( !src || !*src || !dst ) { \
        return src; \
    } \
    char* res = dst; \
    while ( *src ) { \
        *dst++ = *src++; \
    } \
    return res; \
} \



Что вернет return ?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Daevaorn
Дата 8.6.2008, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(andrew_121 @  8.6.2008,  15:06 Найти цитируемый пост)
Что вернет return ? 

return вернет res. Только этого не будет ожидать клиентский код . Поэтому, во все макросы надо добавить ещё один параметр, куда записывать результат.
PM MAIL WWW   Вверх
andrew_121
Дата 8.6.2008, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Daevaorn: Примерчик можно...

Есть еще мнения?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
mes
Дата 8.6.2008, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(andrew_121 @  8.6.2008,  14:06 Найти цитируемый пост)
#define strcmp(dst, src) { \
    if ( !src || !*src || !dst ) { \
        return src; \
    } \
    char* res = dst; \
    while ( *src ) { \
        *dst++ = *src++; \
    } \
    return res; \
} \

при использовании макроса будет построена следуюшая комбинация
Код


вместо: strcmp(src,dst) 
будет :
{
    if ( !src || !*src || !dst ) {       return src;    }
    char* res = dst; 
    while ( *src ) {      *dst++ = *src++;     } 
    return res; 
} 


// то есть построится тело функции , а это совсем не то что вы хотели 
// хотя что именно хотели получить , не понятно
// если функцию стравнения для любого типа (то непонятно тогда почему название strcmp)- то смотреть в сторону шаблона
// если функцию для сравнения строк то #define там не нужен





--------------------
PM MAIL WWW   Вверх
baldina
Дата 8.6.2008, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



макрос должен представлять выражение, имеющее значение. естественно, никаких return
как-то так: 
Код

#define strcmp(_res, _s1, _s2) { \
  char *s1=_s1, *s2=_s2; \
   while (*_s1 && (_res=*s2++-*s1++)==0); \
 }

PM MAIL   Вверх
andrew_121
Дата 8.6.2008, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



mes: Что получиться я заню, от этого и вопрос - Как из тела функции в виде макроса, получить результат ???

Добавлено через 4 минуты и 40 секунд
baldina: Спасибо. Щас буду тестить.
По идее такая реализация строковых функций должна работать быстрее стандартной.
А какие подводные камни появятся...?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
baldina
Дата 8.6.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



про выражение написал, а значения не показал  smile 
не получится тут "вернуть", нужен параметр макроса для результата

Добавлено через 4 минуты и 45 секунд
Цитата

такая реализация строковых функций должна работать быстрее стандартной

отнюдь. стандартная на ассемблере написана smile 
если надо избежать накладные расходы на вызов функции, используй inline 
кстати, современные компиляторы умеют в режиме оптимизации встраивать такие функции как strcmp, strcpy, pow, sqrt, sin и т.п. (intrinsic functions)
PM MAIL   Вверх
andrew_121
Дата 8.6.2008, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата

кстати, современные компиляторы умеют в режиме оптимизации встраивать такие функции как strcmp, strcpy, pow, sqrt, sin и т.п. (intrinsic functions)


Знаю про это.
Но практика показывает, что это не всегда происходит. И не понятно от чего и почему...


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lazin
Дата 8.6.2008, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(andrew_121 @  8.6.2008,  14:15 Найти цитируемый пост)
Есть еще мнения?

макросы для этих целей использовать нельзя, это дурной тон.
Как уже было сказано, компилятор в состоянии сам определить, где требуется функцию вызвать а где ее лучше встроить. 
В случае использования макросов таким вот образом, страдает ясность кода, большинство IDE не смогут сделать подсказку для макроса, статические анализаторы кода то-же отдыхают. 
К тому-же, возможны тяжело обнаруживаемые ошибки.
PM MAIL Skype GTalk   Вверх
mes
Дата 8.6.2008, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(andrew_121 @  8.6.2008,  14:31 Найти цитируемый пост)
Что получиться я заню, от этого и вопрос - Как из тела функции в виде макроса, получить результат ???

не использовать слово return, например
#define test(dst, src)  ( !src || !*src || !dst ) ? src : dst

но в любом случае не понятна цель - если для скорости - то такой путь заблуждение


--------------------
PM MAIL WWW   Вверх
Lazin
Дата 8.6.2008, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(andrew_121 @  8.6.2008,  14:58 Найти цитируемый пост)
Знаю про это.
Но практика показывает, что это не всегда происходит. И не понятно от чего и почему... 

это происходит, для того, что-бы уменьшить объем кода.
там где это может дать увеличение производительности, например в цикле, встраивание происходит. если функция вызывается всего один раз, то экономить пару наносекунд тратящихся на ее вызов нет смысла smile 
PM MAIL Skype GTalk   Вверх
andrew_121
Дата 8.6.2008, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



mes: Да, для скорости...
Так как большие изменения в программу вносить не хочется.
Это один из простых способов.

Добавлено @ 15:24
Вот что я сделал:
Код

#define mystrcmp2(_res, _s1, _s2) { \
    char *s1=_s1, *s2=_s2; \
    while (*s1 && (_res=*s2++-*s1++)==0); \
}
 
int main() {

    char str1[128] = "abcdef";
    char str2[128] = "abcdef";
    int res = 0;
    
    mystrcmp2( res, str1, str2 );
    
    printf( (res == 0) ? "res = %d string is equal!\n" : "res = %d string is not equal!\n", res );
    
    return res;
}



Гну препроцессор сотворяет вот что:
Код

int main() {

 char str1[128] = "abcdef";
 char str2[128] = "abcdef";
 int res = 0;

 { char *s1=str1, *s2=str2; while (*s1 && (res=*s2++-*s1++)==0); };

 printf( (res == 0) ? "res = %d string is equal!\n" : "res = %d string is not equal!\n", res );

 return res;
}


Но почему-то res = 84, а не 0.
Первый недостаток макросов - хрен отладишь!!!

А...вот опечатка:  while (*s1 && (res=*s2++-*s1++)==0);

Это сообщение отредактировал(а) andrew_121 - 8.6.2008, 15:33


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
MAKCim
Дата 8.6.2008, 15:31 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



в GCC решение такое
Код

#define strcmp(dst, src) {( \
    if ( !src || !*src || !dst ) src; \
    char* res = dst; \
    while (*src++ = *dst++); \
    res; })

Цитата

A compound statement enclosed in parentheses may appear as an expression in GNU C.
This allows you to use loops, switches, and local variables within an expression.

в коде ядра Linux данное расширение широко используется

Это сообщение отредактировал(а) MAKCim - 8.6.2008, 15:34


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
andrew_121
Дата 8.6.2008, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



MAKCim Т.е. запись вида:
Код

char* result = strcmp( "abcdef", "abcdef" );

Будет трактоваться как:
Код

char* result = src || res

В зависимости от результата...?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
MAKCim
Дата 8.6.2008, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(andrew_121 @  8.6.2008,  15:38 Найти цитируемый пост)
В зависимости от результата...? 

да, только, наверное, макрос должен называться strcpy, а не strcmp  smile 

Это сообщение отредактировал(а) MAKCim - 8.6.2008, 15:40


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0761 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.