I would like some feedback on a CMakeLists.txt file I created for compiling my project. I have pasted the CMakeLists as well as my source code below. One thing I would specifically appreciate feedback on the sanitization options I have enabled. Are there more I should enable, and/or should I should reduce? I know -fsanitize=address, -fsanitize=thread, and -fsanitize=memory
groups can't be used with others (according to the clang documentation). Would one of the other groups be better preferred to use on a first-pass rather than the one I chose (address
)?
Also - the blob feature I am using, I have based on a StackOverflow answer I read - I understand that this doesn't detect new C source files and I'm fine with that, but besides that subtle detail is this an okay practice to follow?
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(FirstProject C)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_STANDARD 99)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default")
FILE(GLOB Sources *.c)
add_executable(${CMAKE_PROJECT_NAME} ${Sources})
target_link_libraries(${CMAKE_PROJECT_NAME} ${CURSES_LIBRARIES})
main.c (Code comes from here)
#include <ctype.h> #include <errno.h> #include <inttypes.h> #include <limits.h> #include <ncurses.h> #include <stdint.h> #include <stdlib.h> #include <string.h> // Generous estimate of the maximum number of digits // https://stackoverflow.com/a/10536254 #define ULL_DIGITS (3 * sizeof(unsigned long long)) #define ERR_MSG_MAX_LENGTH 32 #define NUL '\0' #define NUL_SIZE 1 int ask_ull(unsigned long long *result, const char *prompt); /** * Prints a prompt then reads an unsigned long long, using ncurses. * Returns 0 on success. Returns errno on failure, which is set to * ERANGE, EDOM, or EIO. */ int ask_ull(unsigned long long *result, const char *prompt) { char buf[ULL_DIGITS + NUL_SIZE]; char *endptr; printw("%s", prompt); getnstr(buf, ULL_DIGITS); *result = strtoull(buf, &endptr, 10); if (errno == ERANGE) { // Overflow or underflow return errno; } if (endptr == buf || strchr(buf, '-')) { // Unsuccessful conversion errno = EDOM; return errno; } while (isspace(*endptr)) endptr++; if (*endptr) { // Trailing junk errno = EIO; return errno; } errno = 0; return errno; } int main(void) { unsigned long long height, width, length; height = width = length = 0; char errmsg[ERR_MSG_MAX_LENGTH]; errmsg[0] = NUL; initscr(); printw("--- Volume Calculator --\n"); if (!ask_ull(&length, "Enter length: ")) { sscanf(errmsg, "%s", "Unable to scan length"); } if (!ask_ull(&width, "Enter width: ")) { sscanf(errmsg, "%s", "Unable to scan width"); } if (!ask_ull(&height, "Enter height: ")) { sscanf(errmsg, "%s", "Unable to scan height"); } if (errmsg[0] != NUL) { refresh(); endwin(); perror(errmsg); return errno; } unsigned long long volume = length * width * height; printw("Volume: %llu", volume); refresh(); getch(); endwin(); }