Константный указатель на константные данные из указателя на указатель

#include <stdio.h>
#include <iso646.h>
#include <stdlib.h> 

#define FAIL exit(EXIT_FAILURE);

void check_params(const int params_count, char ** params) // const char ** const params - error
{
    if (not ((params_count == 2) and (params != NULL) and (params[1] != NULL)))
    {
        puts("Input params check failed. Program terminated.");
    
        FAIL
    }
}

int main(int params_count, char * params[])
{           
    check_params(params_count, params);     
}

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

UPDATE Вариант решения, предложенный @Harry, выдаёт ошибку:

$ gcc test.c -Wall -Wextra --pedantic --std=c23
   test.c: In function ‘main’:
   test.c:19:32: error: passing argument 2 of ‘check_params’ from incompatible pointer type [-Wincompatible-pointer-types]
  19 |     check_params(params_count, params);
     |                                ^~~~~~
     |                                |
     |                                char **
   test.c:7:70: note: expected ‘const char * const* const’ but argument is of type ‘char **’
   7 | void check_params(const int params_count, const char * const * const params)

Ответы (1 шт):

Автор решения: LolPopGames

Как уже сказал @Harry, params должен быть const char * const * const, т.е. :

void check_params(const int params_count, const char * const * const params);

И как подметил @wololo, неявное преобразование обычного указателя в константный недопустимо стандартом C

Т.е. в вызове нужно явно преобразовать тип:

// main
check_params(params_count, (const char * const * const)params);

Если не устраивает то, что тип слишком долго писать, то можно сделать typedef

typedef const char * const * const params_t;

И использовать его

Полный код получился следующий:

#include <stdio.h>
#include <iso646.h>
#include <stdlib.h> 

#define FAIL exit(EXIT_FAILURE);

typedef const char * const * const params_t;

void check_params(const int params_count, params_t params)
{
    if (not ((params_count == 2) and (params != NULL) and (params[1] != NULL)))
    {
        puts("Input params check failed. Program terminated.");
    
        FAIL
    }
}

int main(int params_count, char *params[])
{           
    check_params(params_count, (params_t)params);
}
→ Ссылка