MIN і MAX в С


299

Де вони MINі MAXвизначені в C, якщо вони взагалі?

Який найкращий спосіб здійснити їх, максимально безпечно та ввести безпечно? (Розширення компілятора / вбудовані для основних компіляторів бажано.)

Відповіді:


392

Де вони MINі MAXвизначені в C, якщо вони взагалі?

Вони ні.

Який найкращий спосіб здійснити їх, максимально безпечно та набрати безпечніше (переважні розширення / вбудовані компілятори для основних компіляторів).

Як функції. Я б не використовував такі макроси #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)), особливо якщо ви плануєте розгорнути свій код. Або написати своє власне, використовувати що - щось на зразок стандарту fmaxабо fmin, або виправити макрос з допомогою TYPEOF GCC в (ви отримаєте бонус тіпобезопасності теж) в вираженні МКІ заяви :

 #define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

Всі кажуть: "О, я знаю про подвійне оцінювання, це не проблема", і через кілька місяців ви будете налагоджувати найбільш глупі проблеми протягом багатьох годин.

Зверніть увагу на використання __typeof__замість typeof:

Якщо ви пишете файл заголовка, який повинен працювати, якщо він включений до програм ISO C, пишіть __typeof__замість typeof.


68
Ви знаєте, було б досить зручно, якби gcc попередив: " warning: expression with side-effects multiply evaluated by macroна місці використання ...
caf

23
@caf: чи не вимагатиме від препроцесора складніших знань синтаксису С?
dreamlax

3
Після багатьох спроб розібратися, я не думаю, що це все-таки можна зробити в VC ++, але найкраще - спробувати поплутатися з новим decltypeключовим словом MSVC ++ 2010 - але навіть так, Visual Studio не може робити складні заяви у макросах (і decltypeце C ++ у будь-якому випадку), тобто ({ ... })синтаксис GCC, тому я впевнений, що це все-таки неможливо. Я не дивився на жодних інших упорядників щодо цього питання, вибачте Лютер: S
Девід Тітаренко

7
@dreamlax Я колись бачив випадок, коли хтось робив MAX(someUpperBound, someRandomFunction())для обмеження випадкового значення якоюсь верхньою межею. Це була жахлива ідея, але вона навіть не спрацювала, тому що MAXвін використовував проблему з подвійним оцінюванням, тож він опинився з іншим випадковим числом, ніж те, що було оцінено спочатку.
Зев Айзенберг

8
@Soumen Наприклад, якщо ви зателефонуєте MIN(x++, y++)до препроцесора, генерується наступний код (((x++) < (y++)) ? (x++) : (y++)). Отже, xі yбуде збільшуватися вдвічі.
Антоніо

91

Він також надається у версіях GNU libc (Linux) та FreeBSD для sys / param.h та має визначення, яке надає dreamlax.


На Debian:

$ uname -sr
Linux 2.6.11

$ cat /etc/debian_version
5.0.2

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

$ head -n 2 /usr/include/sys/param.h | grep GNU
This file is part of the GNU C Library.

На FreeBSD:

$ uname -sr
FreeBSD 5.5-STABLE

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

Вихідні сховища тут:


Визначення із систем, до яких я маю доступ, я додав у своїй відповіді вище (поле коментарів не приймає форматування, наскільки я можу сказати). Спробуємо знайти посилання на джерело репост FreeBSD / Linux / glibc.
Мікель

+1. Дуже хороший. Працює для openSUSE/Linux 3.1.0-1.2-desktop/ gcc version 4.6.2 (SUSE Linux) теж. :) Погано, що це не портативно.
Джек

Працює і на Cygwin.
CMCDragonkai

1
Зачекайте хвилинку. Це не заважає подвійному оцінюванню, чи не так? : 3
користувач1857492

76

Є std::minі std::maxв C ++, але AFAIK, у стандартній бібліотеці С немає еквівалента. Ви можете визначити їх самостійно за допомогою макросів

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

Але це спричиняє проблеми, якщо ви пишете щось подібне MAX(++a, ++b).


10
чому ставити занадто багато дужок ??? Я знайшов вікторину, де вони сказали, що #define MIN(A, B) ((A < B) ? A : B)це не гнучкий спосіб, чому ???

78
@Makouda: Додаткові дужки в макросах допомагають уникнути проблем пріоритетності оператора. Наприклад, розглянемо #define MULT(x, y) x * y. Потім MULT(a + b, a + b)розширюється на a + b * a + b, який розбирає як a + (b * a) + bза рахунок переваги. Це, мабуть, не планував програміст.
dan04

що не потрібно, коли ?: має найнижчий пріоритет у будь-якому випадку
Вінгер Сендон

@WingerSendon: Це не так; робить оператор комами.
dan04

24

Уникайте нестандартних розширень компілятора та впроваджуйте його як повністю безпечний для макросу тип чистого стандарту C (ISO 9899: 2011).

Рішення

#define GENERIC_MAX(x, y) ((x) > (y) ? (x) : (y))

#define ENSURE_int(i)   _Generic((i), int:   (i))
#define ENSURE_float(f) _Generic((f), float: (f))


#define MAX(type, x, y) \
  (type)GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))

Використання

MAX(int, 2, 3)

Пояснення

Макрос MAX створює ще один макрос на основі typeпараметра. Цей макрос управління, якщо він реалізований для даного типу, використовується для перевірки відповідності обох параметрів правильного типу. Якщо значення typeне підтримується, виникла помилка компілятора.

Якщо x або y не є правильним типом, у програмі буде помилка компілятора ENSURE_ макросах . Більше таких макросів можна додати, якщо підтримується більше типів. Я припускав, що застосовуватимуться лише типи арифметики (цілі числа, плавці, покажчики тощо), а не структури та масиви тощо.

Якщо всі типи правильні, буде викликано макрос GENERIC_MAX. Додаткові дужки потрібні навколо кожного параметра макросу, як звичайна стандартна обережність при написанні макросів C.

Потім виникають звичайні проблеми з неявними просуваннями в C. ?:Оператор врівноважує 2-й і 3-й операнди один проти одного. Наприклад, результатом GENERIC_MAX(my_char1, my_char2)буде ан int. Щоб запобігти макросу робити такі потенційно небезпечні рекламні типи, було використано остаточний тип передачі на призначений тип.

Обґрунтування

Ми хочемо, щоб обидва параметри макроса були одного типу. Якщо одна з них має інший тип, макрос більше не є безпечним, оскільки оператор любить?: , дає неявні рекламні акції. А оскільки це так, нам також завжди потрібно повернути кінцевий результат до запланованого типу, як пояснено вище.

Макрос із лише одним параметром можна було записати набагато простіше. Але з 2 або більше параметрами необхідно включити параметр додаткового типу. Тому що щось подібне, на жаль, неможливо:

// this won't work
#define MAX(x, y)                                  \
  _Generic((x),                                    \
           int: GENERIC_MAX(x, ENSURE_int(y))      \
           float: GENERIC_MAX(x, ENSURE_float(y))  \
          )

Проблема полягає в тому, що якщо вищезазначений макрос викликається як MAX(1, 2)два int, він все одно намагатиметься розширити всі можливі сценарії списку _Genericасоціацій. Тож ENSURE_floatмакрос також розшириться, навіть якщо він не стосується int. А оскільки цей макрос навмисно містить лише floatтип, код не буде компілюватися.

Щоб вирішити це, я створив ім’я макроса під час фази перед процесором, за допомогою оператора ##, щоб жоден макрос не випадково розширився.

Приклади

#include <stdio.h>

#define GENERIC_MAX(x, y) ((x) > (y) ? (x) : (y))

#define ENSURE_int(i)   _Generic((i), int:   (i))
#define ENSURE_float(f) _Generic((f), float: (f))


#define MAX(type, x, y) \
  (type)GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))

int main (void)
{
  int    ia = 1,    ib = 2;
  float  fa = 3.0f, fb = 4.0f;
  double da = 5.0,  db = 6.0;

  printf("%d\n", MAX(int,   ia, ib)); // ok
  printf("%f\n", MAX(float, fa, fb)); // ok

//printf("%d\n", MAX(int,   ia, fa));  compiler error, one of the types is wrong
//printf("%f\n", MAX(float, fa, ib));  compiler error, one of the types is wrong
//printf("%f\n", MAX(double, fa, fb)); compiler error, the specified type is wrong
//printf("%f\n", MAX(float, da, db));  compiler error, one of the types is wrong

//printf("%d\n", MAX(unsigned int, ia, ib)); // wont get away with this either
//printf("%d\n", MAX(int32_t, ia, ib)); // wont get away with this either
  return 0;
}

Цей GENERIC_MAXмакрос, до речі, погана ідея, вам потрібно лише спробувати GENERIC_MAX(var++, 7)з’ясувати, чому :-) У наш час (особливо з сильно оптимізуючими / вбудованими компіляторами) макроси мають бути значною мірою віднесені лише до простих форм. Функціональні є кращими як функції, а групи значень - кращими як перерахування.
paxdiablo

21

Я не думаю, що це стандартизовані макроси. Уже є стандартизовані функції для плаваючої точки, fmaxі fminfmaxfдля поплавців, і fmaxlдля довгих пар).

Ви можете реалізовувати їх як макроси, якщо вам відомі проблеми побічних ефектів / подвійної оцінки.

#define MAX(a,b) ((a) > (b) ? a : b)
#define MIN(a,b) ((a) < (b) ? a : b)

У більшості випадків ви можете залишити його компілятору, щоб визначити, що ви намагаєтеся зробити, та оптимізувати це якнайкраще. Хоча це спричиняє проблеми при такому використанні MAX(i++, j++), я сумніваюся, що коли-небудь виникає велика потреба у перевірці максимальних значень збільшення за один раз. Зростання спочатку, потім перевірка.


Це має бути кращою відповіддю, оскільки в математичній бібліотеці чітко є функції min та max: cplusplus.com/reference/cmath/fmax
imranal

@imranal Про що ви конкретно говорите? Код реалізації цих бібліотек? Але цей код не піддається впливу , тобто вони не розміщують його в інтерфейсі бібліотеки, оскільки є потенційно небезпечним.
Антоніо

@Antonio Я думаю, що ви використовуєте неправильні визначення поняття "експозиція" та "інтерфейс". Інтерфейс бібліотеки змінного струму - це зовнішні змінні, типи, макроси та декларації функцій у файлі заголовка; fmin / fmax оголошуються у файлі заголовка, тому вони, як кажуть, піддаються впливу. Я не впевнений, що ви називаєте небезпечним.
раціональнийкодер

21

Це пізня відповідь, зумовлена ​​досить недавньою подією. Оскільки ОП прийняла відповідь, що спирається на непереносне розширення GCC (та клаксони) typeof- або __typeof__на «чистий» ISO C - є краще рішення, що стосується gcc-4.9 .

#define max(x,y) ( \
    { __auto_type __x = (x); __auto_type __y = (y); \
      __x > __y ? __x : __y; })

Очевидною перевагою цього розширення є те, що кожен макроаргумент розгортається лише один раз, на відміну від __typeof__рішення.

__auto_typeє обмеженою формою C ++ 11-х auto. Він не може (або не повинен?) Використовуватись у коді C ++, хоча немає жодної вагомої причини не використовувати можливості вищого типу виводу autoпри використанні C ++ 11.

При цьому, я припускаю, що немає проблем із використанням цього синтаксису, коли макрос включений уextern "C" { ... } область; наприклад, із заголовка С. AFAIK, це розширення не знайшло свого інформаційного дзвінка


Пов’язаний з коментарем Бретта Хейла , clangпочав підтримуватись __auto_typeблизько 2016 року (див. Виправлення ).
Ларс

Kudos для розпізнавання макропроблеми, але я все-таки вважаю, що функція, ймовірно, буде кращою :-)
paxdiablo

@paxdiablo - Я згоден, хоча питання має c-preprocessorтег. Функція не гарантується, що вона буде окреслена навіть із вказаним ключовим словом, якщо тільки не використовується щось на зразок __always_inline__атрибута gcc .
Бретт Хейл

11

Я написав цю версію, яка працює для MSVC, GCC, C та C ++.

#if defined(__cplusplus) && !defined(__GNUC__)
#   include <algorithm>
#   define MIN std::min
#   define MAX std::max
//#   define TMIN(T, a, b) std::min<T>(a, b)
//#   define TMAX(T, a, b) std::max<T>(a, b)
#else
#       define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
                ({ \
                        decltype(lexpr) lvar = (lexpr); \
                        decltype(rexpr) rvar = (rexpr); \
                        lvar binoper rvar ? lvar : rvar; \
                })
#       define _CHOOSE_VAR2(prefix, unique) prefix##unique
#       define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#       define _CHOOSE(binoper, lexpr, rexpr) \
                _CHOOSE2( \
                        binoper, \
                        lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
                        rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
                )
#       define MIN(a, b) _CHOOSE(<, a, b)
#       define MAX(a, b) _CHOOSE(>, a, b)
#endif

Я схвалив, але ідентифікатори, що починаються з підкреслення після великої літери, зарезервовані.
dreamlax

8

Якщо вам потрібен min / max, щоб уникнути дорогого відділення, вам не слід використовувати потрійний оператор, оскільки він складеться до стрибка. Посилання нижче описує корисний метод для реалізації функції min / max без розгалуження.

http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax


1
Якщо компілятор досить розумний, він може уникнути гілки
Axel Gneiting

2
Якщо ввімкнено оптимізацію, всі сучасні компілятори будуть передавати умовний хід замість гілки в більшості випадків, тому використання хаків, як це, мало сенсу.
Кшиштоф Косінський

1
Абсолютно правда, я поняття не маю, на що я дивився тоді, минув час. І gcc, і clang уникають гілок з -O, як на x86, так і на armv7a.
cib

6

@David Titarenco прибив це сюди , але дозвольте мені принаймні трохи очистити його, щоб він виглядав красиво, і покажіть як min() і max() разом, щоб полегшити копіювання та вставлення звідси. :)

Оновлення 25 квітня 2020 року: Я також додав Розділ 3, щоб показати, як це можна зробити з шаблонами C ++, як цінне порівняння для тих, хто навчається як C, так і C ++, або переходить від одного до іншого. Я зробив все можливе, щоб бути ретельним, фактичним і правильним, щоб зробити цю відповідь канонічною довідкою, на яку я можу повертатися знову і знову, і сподіваюся, що ви вважаєте її такою ж корисною, як і я.

1. Старий макро спосіб C:

Ця методика зазвичай використовується, добре поважається тими, хто знає, як правильно її використовувати, "фактичним" способом робити речі, і прекрасно використовувати, якщо правильно користуватися, але баггі (подумайте: побічний ефект подвійної оцінки ), якщо ви коли-небудь передавати вирази, включаючи призначення змінної для порівняння:

#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))

2. Новий і вдосконалений gcc " вираз вираз " спосіб:

Ця методика дозволяє уникнути вищевказаних побічних ефектів та помилок, подвійних оцінок, і тому вважається вищим, безпечнішим та «більш сучасним» способом GCC C для цього. Очікуйте, що він буде працювати як з компіляторами gcc, так і з clang, оскільки clang за задумом сумісний з gcc (див. Примітку clang внизу цієї відповіді).

АЛЕ: НЕ слідкуйте за ефектами " змінного затінення " все-таки, оскільки вирази виразів очевидно підкреслені, і тому НЕ мають власної локальної змінної області!

#define max(a,b)             \
({                           \
    __typeof__ (a) _a = (a); \
    __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b;       \
})

#define min(a,b)             \
({                           \
    __typeof__ (a) _a = (a); \
    __typeof__ (b) _b = (b); \
    _a < _b ? _a : _b;       \
})

Зауважимо, що у виразах gcc заяви, останній вираз у блоці коду - це те, що "повертається" з виразу, як би воно було повернуте з функції. Документація GCC говорить про це так:

Останнє у складеному висловленні має бути виразом, за яким слідує крапка з комою; значення цього підвираження служить значенням всієї конструкції. (Якщо ви використовуєте якийсь інший вид оператора, який триває в дужках, конструкція має тип void і, таким чином, фактично не має значення.)

3. Спосіб шаблону C ++:

Примітка C ++: якщо ви використовуєте C ++, шаблони, ймовірно, рекомендуються для цього типу конструкцій, але я особисто не люблю шаблони, і, мабуть, я б використовував один із перерахованих конструкцій у C ++, так як я часто використовую і віддаю перевагу стилям C у вбудованому C ++.

До цього розділу додано 25 квітня 2020 року:

Я робив тонну C ++ за останні кілька місяців, і тиск віддавати перевагу шаблонам над макросами, де це можливо, у спільноті C ++ є досить сильним. Як результат, я все краще використовую шаблони, і хочу ввести сюди версії шаблонів C ++ для повноти і зробити це більш канонічним і ретельним відповіддю.

Ось як виглядають основні версії шаблонів функційmax() та як вони min()можуть виглядати на C ++:

template <typename T>
T max(T a, T b)
{
    return a > b ? a : b;
}

template <typename T>
T min(T a, T b)
{
    return a < b ? a : b;
}

Тут можна прочитати додаткові шаблони C ++: Вікіпедія: Шаблон (C ++) .

Однак і те, max()і min()вже є частиною стандартної бібліотеки C ++, у <algorithm>заголовку ( #include <algorithm>). У стандартній бібліотеці С ++ вони визначаються дещо інакше, ніж я їх вище. За замовчуванням прототипи std::max<>()і std::min<>(), наприклад, в C ++ 14, дивлячись на свої прототипи в cplusplus.com посилання трохи вище, є:

template <class T> 
constexpr const T& max(const T& a, const T& b);

template <class T> 
constexpr const T& min(const T& a, const T& b);

Зауважте, що ключове слово typenameє псевдонімом class(тому їх використання є тотожним чи ви говорите <typename T>чи <class T>), оскільки пізніше було визнано після винаходу шаблонів C ++, що тип шаблону може бути регулярним типом ( int,float і т.д.) , а не тільки тип класу.

Тут ви бачите, що обидва типи вводу, а також тип повернення є const T&, що означає "постійне посилання на тип T". Це означає, що вхідні параметри та значення повернення передаються посиланням, а не передаються за значенням . Це як проходження повз покажчиків, і є більш ефективним для великих типів, наприклад об'єктів класу. constexprЧастина функції змінює саму функцію , і вказує на те, що функція повинна бути здатна оцінюється під час компіляції ( по крайней мере , якщо це передбаченоconstexpr вхідних параметрів), але якщо вона не може бути оцінена під час компіляції, то він по замовчуванням назад в оцінка часу виконання, як і будь-яка інша нормальна функція.

Аспект часу компіляції constexprфункції C ++ робить його на зразок C-макроподібним, оскільки, якщо оцінка часу компіляції є можливою для constexprфункції, вона буде зроблена під час компіляції, як можливо, MIN()або MAX()заміщення макросу, можливо також буде повністю оцінено під час компіляції в C або C ++. Додаткові посилання на цю інформацію про шаблон C ++ див. Нижче.

Список літератури:

  1. https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof
  2. https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs
  3. MIN і MAX в С
  4. Додано додаткові посилання на шаблон C ++ квітня 2020 року:
    1. ***** Вікіпедія: Шаблон (C ++) <- ВЕЛИКА додаткова інформація про шаблони C ++!
    2. (Моє власне запитання та відповідь): Чому `constexpr` є частиною прототипу шаблону C ++ 14 для` std :: max () `?
    3. Різниця між `constexpr` та` const`

Нота Кланг з Вікіпедії :

[Clang] призначений для того, щоб виконувати функцію заміни колекції GNU Compiler Collection (GCC), підтримуючи більшість його прапорів компіляції та неофіційних розширень мови.


Для спонсора за останні 24 години: хороші новини! Я вчера видалив свою розсилку в розділі 4, яку я додав до розділу 3, і замість цього я поставив її . Запрошуємо переоцінити мою відповідь і дати їй підсумок, якщо вам подобається, оскільки я вклав у неї багато хорошої інформації і зробив усе можливе, щоб зробити це твердою, корисною, канонічною відповіддю, щоб принести користь усім. Тепер це знову зосереджено. :) Дякую!
Габріель Степлес

4

Варто зазначити, я думаю, що якщо ви визначитеся minі maxз третім, таким як

#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

то для отримання однакового результату для особливого випадку fmin(-0.0,0.0)і fmax(-0.0,0.0)вам потрібно поміняти аргументи

fmax(a,b) = MAX(a,b)
fmin(a,b) = MIN(b,a)

Все ще не буде працювати для NaN. fmin(3.0,NaN)==fmin(NaN,3.0)==fmax(3.0,NaN)==fmax(NaN,3.0)==3.0
greggo

@greggo, я дав кращу відповідь тут stackoverflow.com/a/30915238/2542702
Z boson

4

Схоже, макроси Windef.h(а-ля #include <windows.h>) мають maxі min(малі регістри), які також страждають від труднощів з "подвійною оцінкою", але вони є для тих, хто не хоче повторно прокручувати свою :)


12
Ви навіть здивовані?
Метт Столяр

2

Я знаю, хлопець сказав "С" ... Але якщо у вас є шанс, використовуйте шаблон C ++:

template<class T> T min(T a, T b) { return a < b ? a : b; }

Введіть безпечний і не мати проблем із ++, згаданим в інших коментарях.


16
Аргументи повинні бути посиланнями const, ви ніколи не знаєте, що передасть користувач.
nmikhailov

6
Така функція вже стандартизована ( std :: min ).
dreamlax

У C ++ є багато стандартних функцій для більшості звичайних цілей, не винаходити колесо. Однак MS також визначає свій власний min / max, який іноді спричиняє проблеми
phuclv

0

Максимум два цілих числа aі bє (int)(0.5((a+b)+abs(a-b))). Це також може працювати з (double)і fabs(a-b)для парних пар (схоже на поплавці)


Вибачте, якщо це неправильно, я початківець C, але цей код працює для мене
NRZ

2
Я не впевнений, що це працює з не цілими числами. Математика з плаваючою комою має нелінійну точність.
Treesrule14

Щоб розширити коментар @ Treesrule14: Це не працює, оскільки комп'ютери не розглядають числа так само, як математики. Плаваюча точка має проблеми з округленням, тому ви навряд чи отримаєте правильну відповідь. Навіть якщо ви використовуєте цілі математики, MAX_INT + MAX_INT дає -2, тому макс (MAX_INT, MAX_INT) за допомогою вашої формули вийде як -1.
user9876

-3

Найпростіший спосіб - визначити його як глобальну функцію у .hфайлі та викликати її коли завгодно, якщо ваша програма є модульною з великою кількістю файлів. Якщо ні, double MIN(a,b){return (a<b?a:b)}це найпростіший спосіб.


1
@technosaurus Було б корисно, якби ви описали, чому це рішення неправильне, а не лише те, що воно є.
Tur1ng

@technosaurus, ваша відповідь справді не корисна. Під час перегляду1, здається, що функція визначена повністю неправильно (відсутні типи у парамах введення, пропущена крапка з комою після оператора повернення), а перетворення вхідних входів у подвійні - це поганий спосіб робити речі, тому тип не повинен бути подвійним. Вираз визначення або висловлювання буде краще тут (наприклад: див. Тут ), але якщо функція, розгляньте можливість зробити одну функцію для цього для типів int32_t, одну для типів uint32_t і одну для типів float або double, для загальної кількості 3 різні функції.
Габріель

1
@GabrielStaples Цю відповідь слід позначити як не відповідь - в цьому немає допомоги. Хоча це може бути використано як приклад того, як бути найправильнішим у найменшій кількості місця. Рекомендуючи глобальні функції в заголовку (не статичний рівномірний вбудований?), Буде порушено код із 2+ одиницями компіляції, навіть не компілюється, іменуючи функцію, як макрос, маючи на увазі вставки, як його 1989, повертаючи дубль без вказаної причини, мається на увазі касти, які сприйдуть застереження в кращому випадку ... і найголовніше, що НЕ ВІДПОВІДАЄТЬСЯ ЗАПИТАННЯм - не загальним, не безпечним для типу та, безумовно, не найкращим способом
технозавр

Кожна з цих проблем заслуговує на подальшу критику, яка не може бути висвітлена досить детально.
технозавр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.