ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
24 марта
1506605 Топик полностью
Eddy_Em (17.03.2025 20:11, просмотров: 151) ответил LightElf на Что правильного-то? В _Generic после типа должно стоять выражение. int16_t : int16_t - бред собачий
Оно таки справилось! 

There's a big problem in macro COMMON_TYPE: _Generic() needs an expression, not type. It cannot be compiled.

Ответ:

#include <stdint.h>
#include <stdio.h>

// Helper function to promote two values to a common type
static inline double promote_to_double(double a, double b) { return a; } // Dummy function
static inline float promote_to_float(float a, float b) { return a; }    // Dummy function
static inline int64_t promote_to_int64(int64_t a, int64_t b) { return a; } // Dummy function
static inline int32_t promote_to_int32(int32_t a, int32_t b) { return a; } // Dummy function
static inline int16_t promote_to_int16(int16_t a, int16_t b) { return a; } // Dummy function

// Macro to determine the common type and promote values
#define PROMOTE(x, y) _Generic((x), \
    int16_t: _Generic((y), \
        int16_t: promote_to_int16, \
        int32_t: promote_to_int32, \
        int64_t: promote_to_int64, \
        float: promote_to_float, \
        double: promote_to_double \
    ), \
    int32_t: _Generic((y), \
        int16_t: promote_to_int32, \
        int32_t: promote_to_int32, \
        int64_t: promote_to_int64, \
        float: promote_to_float, \
        double: promote_to_double \
    ), \
    int64_t: _Generic((y), \
        int16_t: promote_to_int64, \
        int32_t: promote_to_int64, \
        int64_t: promote_to_int64, \
        float: promote_to_float, \
        double: promote_to_double \
    ), \
    float: _Generic((y), \
        int16_t: promote_to_float, \
        int32_t: promote_to_float, \
        int64_t: promote_to_float, \
        float: promote_to_float, \
        double: promote_to_double \
    ), \
    double: _Generic((y), \
        int16_t: promote_to_double, \
        int32_t: promote_to_double, \
        int64_t: promote_to_double, \
        float: promote_to_double, \
        double: promote_to_double \
    ) \
)(x, y)

#define MAX(x, y) ({ \
    typeof(PROMOTE(x, y)) _x = (x); \
    typeof(PROMOTE(x, y)) _y = (y); \
    _x > _y ? _x : _y; \
})

// MIN macro
#define MIN(x, y) ({ \
    typeof(PROMOTE(x, y)) _x = (x); \
    typeof(PROMOTE(x, y)) _y = (y); \
    _x < _y ? _x : _y; \
})

int main() {
    int16_t a = 10;
    int32_t b = 20;
    printf("MAX(%d, %d) = %d\n", a, b, MAX(a, b)); // Promotes to int32_t

    float x = 3.14f;
    double y = 2.71;
    printf("MIN(%.2f, %.2f) = %.2f\n", x, y, MIN(x, y)); // Promotes to double

    int64_t c = 100;
    float d = 50.5f;
    printf("MAX(%ld, %.2f) = %.2f\n", c, d, MAX(c, d)); // Promotes to float

    return 0;
}

Теперь вроде все ОК.

./a.out 
MAX(10, 20) = 20
MIN(3.14, 2.71) = 2.71
MAX(100, 50.50) = 100.00
eddy-em.livejournal.com github.com/eddyem