Skip to content

many code paths use asserts and null checks for the same thing at the same time #835

@sleeptightAnsiC

Description

@sleeptightAnsiC

Nuklear uses following pattern through its source tree:

NK_ASSERT(foo);
NK_ASSERT(bar);
if (!foo || !bar) return;

(where foo and bar are pointers / arguments to some function)

example:

NK_ASSERT(b);
NK_ASSERT(a);
NK_ASSERT(initial_size);
if (!b || !a || !initial_size) return;

This is confusing in many places because (a) there are functions that I would expect to take NULL, e.g. any destructor, but those crash due to assert failing, (b) if a code works just fine with a null check, why does it need to be guarded with assert? and (c) if developer is never able to test those checks, they're not really useful.

I could point to few locations where it does not make much sense. For example nk_font_atlas_clear should work when passing NULL or empty atlas, but the assert causes an unexpected crash [reference]

Is there some specific reason why Nuklear uses this idiom?


For reference, almost every occurrence of this pattern can be found with following AWK script:

Details

$ git clone https://github.com/Immediate-Mode-UI/Nuklear.git
$ cd Nuklear/src

$ awk '                                                                                                                                                                                                                              
function buf_reset() { buf = "" }                                                                                                                                                                                                                              
function buf_append() { buf = buf "\n" FILENAME ":" FNR ":" $0 }                                                                                                                                                                                               
BEGIN { buf_reset() }                                                                                                                                                                                                                                          
/ *NK_ASSERT(.*);/ { buf_append(); next; }                                                                                                                                                                                                                     
/ *if(.*) return;/ { if (buf) { buf_append(); print buf; buf_reset(); } next; }                                                                                                                                                                                
/.*/ { buf_reset(); next; }                                                                                                                                                                                                                                    
' ./*.c

./nuklear_buffer.c:38:    NK_ASSERT(b);
./nuklear_buffer.c:39:    NK_ASSERT(a);
./nuklear_buffer.c:40:    NK_ASSERT(initial_size);
./nuklear_buffer.c:41:    if (!b || !a || !initial_size) return;

./nuklear_buffer.c:54:    NK_ASSERT(b);
./nuklear_buffer.c:55:    NK_ASSERT(m);
./nuklear_buffer.c:56:    NK_ASSERT(size);
./nuklear_buffer.c:57:    if (!b || !m || !size) return;

./nuklear_buffer.c:196:    NK_ASSERT(buffer);
./nuklear_buffer.c:197:    if (!buffer) return;

./nuklear_buffer.c:206:    NK_ASSERT(buffer);
./nuklear_buffer.c:207:    if (!buffer) return;

./nuklear_buffer.c:227:    NK_ASSERT(b);
./nuklear_buffer.c:228:    if (!b) return;

./nuklear_buffer.c:237:    NK_ASSERT(b);
./nuklear_buffer.c:238:    if (!b || !b->memory.ptr) return;

./nuklear_buffer.c:247:    NK_ASSERT(b);
./nuklear_buffer.c:248:    NK_ASSERT(s);
./nuklear_buffer.c:249:    if (!s || !b) return;

./nuklear_button.c:415:    NK_ASSERT(ctx);
./nuklear_button.c:416:    if (!ctx) return;

./nuklear_chart.c:90:    NK_ASSERT(ctx);
./nuklear_chart.c:91:    NK_ASSERT(ctx->current);
./nuklear_chart.c:92:    NK_ASSERT(ctx->current->layout);
./nuklear_chart.c:93:    NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
./nuklear_chart.c:94:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_chart.c:293:    NK_ASSERT(ctx);
./nuklear_chart.c:294:    NK_ASSERT(values);
./nuklear_chart.c:295:    if (!ctx || !values || !count) return;

./nuklear_chart.c:318:    NK_ASSERT(ctx);
./nuklear_chart.c:319:    NK_ASSERT(value_getter);
./nuklear_chart.c:320:    if (!ctx || !value_getter || !count) return;

./nuklear_context.c:12:    NK_ASSERT(ctx);
./nuklear_context.c:13:    if (!ctx) return;

./nuklear_context.c:90:    NK_ASSERT(ctx);
./nuklear_context.c:91:    if (!ctx) return;

./nuklear_context.c:178:    NK_ASSERT(ctx);
./nuklear_context.c:179:    NK_ASSERT(buffer);
./nuklear_context.c:180:    if (!ctx || !buffer) return;

./nuklear_context.c:197:    NK_ASSERT(ctx);
./nuklear_context.c:198:    NK_ASSERT(win);
./nuklear_context.c:199:    if (!ctx || !win) return;

./nuklear_context.c:213:    NK_ASSERT(ctx);
./nuklear_context.c:214:    NK_ASSERT(win);
./nuklear_context.c:215:    if (!ctx || !win) return;

./nuklear_context.c:224:    NK_ASSERT(ctx);
./nuklear_context.c:225:    NK_ASSERT(buffer);
./nuklear_context.c:226:    if (!ctx || !buffer) return;

./nuklear_context.c:236:    NK_ASSERT(ctx);
./nuklear_context.c:237:    NK_ASSERT(win);
./nuklear_context.c:238:    if (!ctx || !win) return;

./nuklear_contextual.c:183:    NK_ASSERT(ctx);
./nuklear_contextual.c:184:    NK_ASSERT(ctx->current);
./nuklear_contextual.c:185:    NK_ASSERT(ctx->current->layout);
./nuklear_contextual.c:186:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_contextual.c:194:    NK_ASSERT(ctx);
./nuklear_contextual.c:195:    NK_ASSERT(ctx->current);
./nuklear_contextual.c:196:    if (!ctx || !ctx->current) return;

./nuklear_draw.c:13:    NK_ASSERT(cb);
./nuklear_draw.c:14:    NK_ASSERT(b);
./nuklear_draw.c:15:    if (!cb || !b) return;

./nuklear_draw.c:25:    NK_ASSERT(b);
./nuklear_draw.c:26:    if (!b) return;

./nuklear_draw.c:72:    NK_ASSERT(b);
./nuklear_draw.c:73:    if (!b) return;

./nuklear_draw.c:93:    NK_ASSERT(b);
./nuklear_draw.c:94:    if (!b || line_thickness <= 0) return;

./nuklear_draw.c:111:    NK_ASSERT(b);
./nuklear_draw.c:112:    if (!b || col.a == 0 || line_thickness <= 0) return;

./nuklear_draw.c:133:    NK_ASSERT(b);
./nuklear_draw.c:134:    if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;

./nuklear_draw.c:156:    NK_ASSERT(b);
./nuklear_draw.c:157:    if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;

./nuklear_draw.c:180:    NK_ASSERT(b);
./nuklear_draw.c:181:    if (!b || rect.w == 0 || rect.h == 0) return;

./nuklear_draw.c:226:    NK_ASSERT(b);
./nuklear_draw.c:227:    if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;

./nuklear_draw.c:265:    NK_ASSERT(b);
./nuklear_draw.c:266:    if (!b || c.a == 0) return;

./nuklear_draw.c:282:    NK_ASSERT(b);
./nuklear_draw.c:283:    if (!b || c.a == 0 || line_thickness <= 0) return;

./nuklear_draw.c:309:    NK_ASSERT(b);
./nuklear_draw.c:310:    if (!b || c.a == 0) return;

./nuklear_draw.c:339:    NK_ASSERT(b);
./nuklear_draw.c:340:    if (!b || col.a == 0 || line_thickness <= 0) return;

./nuklear_draw.c:360:    NK_ASSERT(b);
./nuklear_draw.c:361:    if (!b || col.a == 0) return;

./nuklear_draw.c:381:    NK_ASSERT(b);
./nuklear_draw.c:382:    if (!b || col.a == 0 || line_thickness <= 0) return;

./nuklear_draw.c:399:    NK_ASSERT(b);
./nuklear_draw.c:400:    if (!b) return;

./nuklear_draw.c:499:    NK_ASSERT(b);
./nuklear_draw.c:500:    if (!b) return;

./nuklear_draw.c:525:    NK_ASSERT(b);
./nuklear_draw.c:526:    NK_ASSERT(font);
./nuklear_draw.c:527:    if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;

./nuklear_edit.c:78:    NK_ASSERT(out);
./nuklear_edit.c:79:    NK_ASSERT(font);
./nuklear_edit.c:80:    NK_ASSERT(style);
./nuklear_edit.c:81:    if (!text || !byte_len || !out || !style) return;

./nuklear_edit.c:684:    NK_ASSERT(ctx);
./nuklear_edit.c:685:    NK_ASSERT(ctx->current);
./nuklear_edit.c:686:    if (!ctx || !ctx->current) return;

./nuklear_edit.c:699:    NK_ASSERT(ctx);
./nuklear_edit.c:700:    NK_ASSERT(ctx->current);
./nuklear_edit.c:701:    if (!ctx || !ctx->current) return;

./nuklear_font.c:429:    NK_ASSERT(out_memory);
./nuklear_font.c:430:    NK_ASSERT(in_memory);
./nuklear_font.c:431:    NK_ASSERT(img_width);
./nuklear_font.c:432:    NK_ASSERT(img_height);
./nuklear_font.c:433:    if (!out_memory || !in_memory || !img_height || !img_width) return;

./nuklear_font.c:727:    NK_ASSERT (nk__dout + length <= nk__barrier);
./nuklear_font.c:728:    if (nk__dout + length > nk__barrier) { nk__dout += length; return; }

./nuklear_font.c:735:    NK_ASSERT (nk__dout + length <= nk__barrier);
./nuklear_font.c:736:    if (nk__dout + length > nk__barrier) { nk__dout += length; return; }

./nuklear_font.c:884:    NK_ASSERT(atlas);
./nuklear_font.c:885:    if (!atlas) return;

./nuklear_font.c:898:    NK_ASSERT(atlas);
./nuklear_font.c:899:    NK_ASSERT(alloc);
./nuklear_font.c:900:    if (!atlas || !alloc) return;

./nuklear_font.c:909:    NK_ASSERT(atlas);
./nuklear_font.c:910:    NK_ASSERT(permanent);
./nuklear_font.c:911:    NK_ASSERT(temporary);
./nuklear_font.c:912:    if (!atlas || !permanent || !temporary) return;

./nuklear_font.c:1314:    NK_ASSERT(atlas);
./nuklear_font.c:1315:    NK_ASSERT(atlas->temporary.alloc);
./nuklear_font.c:1316:    NK_ASSERT(atlas->temporary.free);
./nuklear_font.c:1317:    NK_ASSERT(atlas->permanent.alloc);
./nuklear_font.c:1318:    NK_ASSERT(atlas->permanent.free);
./nuklear_font.c:1319:    if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;

./nuklear_font.c:1336:    NK_ASSERT(atlas);
./nuklear_font.c:1337:    NK_ASSERT(atlas->temporary.alloc);
./nuklear_font.c:1338:    NK_ASSERT(atlas->temporary.free);
./nuklear_font.c:1339:    NK_ASSERT(atlas->permanent.alloc);
./nuklear_font.c:1340:    NK_ASSERT(atlas->permanent.free);
./nuklear_font.c:1341:    if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;

./nuklear_group.c:194:        NK_ASSERT(x_offset_ptr);
./nuklear_group.c:195:        NK_ASSERT(y_offset_ptr);
./nuklear_group.c:196:        if (!x_offset_ptr || !y_offset_ptr) return;

./nuklear_group.c:229:        NK_ASSERT(x_offset_ptr);
./nuklear_group.c:230:        NK_ASSERT(y_offset_ptr);
./nuklear_group.c:231:        if (!x_offset_ptr || !y_offset_ptr) return;

./nuklear_image.c:115:    NK_ASSERT(ctx);
./nuklear_image.c:116:    NK_ASSERT(ctx->current);
./nuklear_image.c:117:    NK_ASSERT(ctx->current->layout);
./nuklear_image.c:118:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_image.c:130:    NK_ASSERT(ctx);
./nuklear_image.c:131:    NK_ASSERT(ctx->current);
./nuklear_image.c:132:    NK_ASSERT(ctx->current->layout);
./nuklear_image.c:133:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_input.c:14:    NK_ASSERT(ctx);
./nuklear_input.c:15:    if (!ctx) return;

./nuklear_input.c:33:    NK_ASSERT(ctx);
./nuklear_input.c:34:    if (!ctx) return;

./nuklear_input.c:48:    NK_ASSERT(ctx);
./nuklear_input.c:49:    if (!ctx) return;

./nuklear_input.c:60:    NK_ASSERT(ctx);
./nuklear_input.c:61:    if (!ctx) return;

./nuklear_input.c:76:    NK_ASSERT(ctx);
./nuklear_input.c:77:    if (!ctx) return;

./nuklear_input.c:101:    NK_ASSERT(ctx);
./nuklear_input.c:102:    if (!ctx) return;

./nuklear_input.c:113:    NK_ASSERT(ctx);
./nuklear_input.c:114:    if (!ctx) return;

./nuklear_input.c:128:    NK_ASSERT(ctx);
./nuklear_input.c:129:    if (!ctx) return;

./nuklear_input.c:137:    NK_ASSERT(ctx);
./nuklear_input.c:138:    if (!ctx) return;

./nuklear_layout.c:308:    NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
./nuklear_layout.c:309:    NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
./nuklear_layout.c:310:    if (layout->row.type != NK_LAYOUT_TEMPLATE) return;

./nuklear_layout.c:328:    NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
./nuklear_layout.c:329:    NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
./nuklear_layout.c:330:    if (layout->row.type != NK_LAYOUT_TEMPLATE) return;

./nuklear_layout.c:348:    NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
./nuklear_layout.c:349:    NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
./nuklear_layout.c:350:    if (layout->row.type != NK_LAYOUT_TEMPLATE) return;

./nuklear_layout.c:375:    NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
./nuklear_layout.c:376:    if (layout->row.type != NK_LAYOUT_TEMPLATE) return;

./nuklear_list_view.c:70:    NK_ASSERT(view);
./nuklear_list_view.c:71:    NK_ASSERT(view->ctx);
./nuklear_list_view.c:72:    NK_ASSERT(view->scroll_pointer);
./nuklear_list_view.c:73:    if (!view || !view->ctx) return;

./nuklear_pool.c:37:    NK_ASSERT(size >= sizeof(struct nk_page));
./nuklear_pool.c:38:    if (size < sizeof(struct nk_page)) return;

./nuklear_popup.c:192:    NK_ASSERT(ctx);
./nuklear_popup.c:193:    if (!ctx || !ctx->current) return;

./nuklear_string.c:244:    NK_ASSERT(s);
./nuklear_string.c:245:    NK_ASSERT(len >= 0);
./nuklear_string.c:246:    if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;

./nuklear_string.c:259:    NK_ASSERT(str);
./nuklear_string.c:260:    NK_ASSERT(len >= 0);
./nuklear_string.c:261:    if (!str || len < 0) return;

./nuklear_style.c:112:    NK_ASSERT(ctx);
./nuklear_style.c:113:    if (!ctx) return;

./nuklear_style.c:847:    NK_ASSERT(ctx);
./nuklear_style.c:848:    if (!ctx) return;

./nuklear_style.c:857:    NK_ASSERT(ctx);
./nuklear_style.c:858:    if (!ctx) return;

./nuklear_text.c:17:    NK_ASSERT(o);
./nuklear_text.c:18:    NK_ASSERT(t);
./nuklear_text.c:19:    if (!o || !t) return;

./nuklear_text.c:67:    NK_ASSERT(o);
./nuklear_text.c:68:    NK_ASSERT(t);
./nuklear_text.c:69:    if (!o || !t) return;

./nuklear_text.c:104:    NK_ASSERT(ctx);
./nuklear_text.c:105:    NK_ASSERT(ctx->current);
./nuklear_text.c:106:    NK_ASSERT(ctx->current->layout);
./nuklear_text.c:107:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_text.c:131:    NK_ASSERT(ctx);
./nuklear_text.c:132:    NK_ASSERT(ctx->current);
./nuklear_text.c:133:    NK_ASSERT(ctx->current->layout);
./nuklear_text.c:134:    if (!ctx || !ctx->current || !ctx->current->layout) return;

./nuklear_text.c:260:    NK_ASSERT(ctx);
./nuklear_text.c:261:    if (!ctx) return;

./nuklear_text.c:267:    NK_ASSERT(ctx);
./nuklear_text.c:268:    if (!ctx) return;

./nuklear_text_editor.c:374:    NK_ASSERT(state);
./nuklear_text_editor.c:375:    NK_ASSERT(text);
./nuklear_text_editor.c:376:    if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return;

./nuklear_text_editor.c:997:    NK_ASSERT(state);
./nuklear_text_editor.c:998:    NK_ASSERT(memory);
./nuklear_text_editor.c:999:    if (!state || !memory || !size) return;

./nuklear_text_editor.c:1007:    NK_ASSERT(state);
./nuklear_text_editor.c:1008:    NK_ASSERT(alloc);
./nuklear_text_editor.c:1009:    if (!state || !alloc) return;

./nuklear_text_editor.c:1018:    NK_ASSERT(state);
./nuklear_text_editor.c:1019:    if (!state) return;

./nuklear_text_editor.c:1035:    NK_ASSERT(state);
./nuklear_text_editor.c:1036:    if (!state) return;

./nuklear_tooltip.c:51:    NK_ASSERT(ctx);
./nuklear_tooltip.c:52:    NK_ASSERT(ctx->current);
./nuklear_tooltip.c:53:    if (!ctx || !ctx->current) return;

./nuklear_vertex.c:14:    NK_ASSERT(list);
./nuklear_vertex.c:15:    if (!list) return;

./nuklear_vertex.c:177:    NK_ASSERT(list);
./nuklear_vertex.c:178:    if (!list) return;

./nuklear_vertex.c:191:    NK_ASSERT(list);
./nuklear_vertex.c:192:    if (!list) return;

./nuklear_vertex.c:273:    NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
./nuklear_vertex.c:274:    NK_ASSERT(format <= NK_FORMAT_COLOR_END);
./nuklear_vertex.c:275:    if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;

./nuklear_vertex.c:349:    NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
./nuklear_vertex.c:350:    if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;

./nuklear_vertex.c:424:    NK_ASSERT(list);
./nuklear_vertex.c:425:    if (!list || points_count < 2) return;

./nuklear_vertex.c:665:    NK_ASSERT(list);
./nuklear_vertex.c:666:    if (!list || points_count < 3) return;

./nuklear_vertex.c:782:    NK_ASSERT(list);
./nuklear_vertex.c:783:    if (!list) return;

./nuklear_vertex.c:793:    NK_ASSERT(list);
./nuklear_vertex.c:794:    if (!list) return;

./nuklear_vertex.c:811:    NK_ASSERT(list);
./nuklear_vertex.c:812:    if (!list) return;

./nuklear_vertex.c:827:    NK_ASSERT(list);
./nuklear_vertex.c:828:    if (!list) return;

./nuklear_vertex.c:872:    NK_ASSERT(list);
./nuklear_vertex.c:873:    if (!list) return;

./nuklear_vertex.c:898:    NK_ASSERT(list);
./nuklear_vertex.c:899:    NK_ASSERT(list->path_count);
./nuklear_vertex.c:900:    if (!list || !list->path_count) return;

./nuklear_vertex.c:921:    NK_ASSERT(list);
./nuklear_vertex.c:922:    if (!list) return;

./nuklear_vertex.c:932:    NK_ASSERT(list);
./nuklear_vertex.c:933:    if (!list) return;

./nuklear_vertex.c:943:    NK_ASSERT(list);
./nuklear_vertex.c:944:    if (!list || !col.a) return;

./nuklear_vertex.c:958:    NK_ASSERT(list);
./nuklear_vertex.c:959:    if (!list || !col.a) return;

./nuklear_vertex.c:973:    NK_ASSERT(list);
./nuklear_vertex.c:974:    if (!list || !col.a) return;

./nuklear_vertex.c:999:    NK_ASSERT(list);
./nuklear_vertex.c:1000:    if (!list) return;

./nuklear_vertex.c:1021:    NK_ASSERT(list);
./nuklear_vertex.c:1022:    if (!list || !col.a) return;

./nuklear_vertex.c:1032:    NK_ASSERT(list);
./nuklear_vertex.c:1033:    if (!list || !col.a) return;

./nuklear_vertex.c:1044:    NK_ASSERT(list);
./nuklear_vertex.c:1045:    if (!list || !col.a) return;

./nuklear_vertex.c:1055:    NK_ASSERT(list);
./nuklear_vertex.c:1056:    if (!list || !col.a) return;

./nuklear_vertex.c:1066:    NK_ASSERT(list);
./nuklear_vertex.c:1067:    if (!list || !col.a) return;

./nuklear_vertex.c:1086:    NK_ASSERT(list);
./nuklear_vertex.c:1087:    if (!list) return;

./nuklear_vertex.c:1113:    NK_ASSERT(list);
./nuklear_vertex.c:1114:    if (!list) return;

./nuklear_vertex.c:1143:    NK_ASSERT(list);
./nuklear_vertex.c:1144:    if (!list || !len || !text) return;

./nuklear_window.c:66:    NK_ASSERT(ctx);
./nuklear_window.c:67:    NK_ASSERT(win);
./nuklear_window.c:68:    if (!win || !ctx) return;

./nuklear_window.c:72:        NK_ASSERT(iter != iter->next);
./nuklear_window.c:73:        NK_ASSERT(iter != win);
./nuklear_window.c:74:        if (iter == win) return;

./nuklear_window.c:552:    NK_ASSERT(ctx);
./nuklear_window.c:553:    if (!ctx) return;

./nuklear_window.c:556:    NK_ASSERT(ctx->current != win && "You cannot close a currently active window");
./nuklear_window.c:557:    if (ctx->current == win) return;

./nuklear_window.c:566:    NK_ASSERT(ctx);
./nuklear_window.c:567:    if (!ctx) return;

./nuklear_window.c:609:    NK_ASSERT(ctx);
./nuklear_window.c:610:    if (!ctx) return;

./nuklear_window.c:624:    NK_ASSERT(ctx);
./nuklear_window.c:625:    if (!ctx || !cond) return;

./nuklear_window.c:634:    NK_ASSERT(ctx);
./nuklear_window.c:635:    if (!ctx) return;

./nuklear_window.c:649:    NK_ASSERT(ctx);
./nuklear_window.c:650:    if (!ctx || !cond) return;

./nuklear_window.c:660:    NK_ASSERT(ctx);
./nuklear_window.c:661:    if (!ctx) return;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions