lainchan / λ

All things C

⍕ · 2021-03-11 20:14
The other thread hit bump limit. Let's continue our discussion about the C programming language !
Debbie Charteris · 2021-03-11 20:18
So I am looking for this site where this reluctant dude gives all his advices to write non-soykafty C11 code. I remember his first advice was "Don't write C unless you absolutely have to" or something like that. I am pretty sure I saw it on this board, but I cannot find it anymore.
x<->y · 2021-03-11 21:26
I asked this in simple questions thread, but maybe it's better fit for here. I've been rereading K&R and making notes this time, but this section confuses me (pic related). Aren't all of these actually definitions? I mean literally all of them cause memory to be allocated, which is what ANSI C standard refers to as definition. Hell even in the same book they mention that: >"Definition" refers to the place where the variable is created or assigned storage; "declaration" refers to the places where the nature of the variable is stated but no storage is allocated. [p. 33] >Declarations specify the interpretation given to each identifier; they do not necessarily reserve storage associated with the identifier. Declarations that reserve storage are called definitions. [p. 210] So I guess all of these are declarations, but wouldn't it be much more precise to call them definitions? Very confused right now.
Nanashi No Gombe · 2021-03-11 22:18
>>24830 The terms don't really matter as long as you understand the semantics. I guess the point is that you can declare something at a different place from where you use it, i.e. a forward declaration. >So I guess all of these are declarations, but wouldn't it be much more precise to call them definitions? It seems to be that way. I think the confusion lies in that a declaration can also be a e.g. struct declaration, according to the standard, notice how it says "identifier" and not "variable". It makes more sense to describe it as they do when talking about C89 (and earlier K&R C) where you have to declare all your variables (i.e. the stack memory that your function uses) at the beginning of a function, though this isn't a convention in modern C anymore.
Roy Batty · 2021-03-13 00:21
>>24830 those are both definitions and declarations. `int x;` is both a definition and declaration. `extern int x;` is a declaration only, it tells the compiler that somewhere there's a variable called x, but doesn't allocate memory for it, the compiler expects there to be a definition elsewhere. >>24826 handmade hero "intro to c on windows"? https://guide.handmadehero.org/intro-to-c/
Guthrie · 2021-03-13 04:08
>>24824 Currently working on exercise 1-18 in K&R, this is my attempted solution. Any idea why it isn't working? #include <stdio.h> #include <string.h> #include <unistd.h> #define BUF_SIZE 4096 char* filter_line (char s[]) { int last_char = 0; for (int i = 0; i < BUF_SIZE; ++i) { if (s[i] <= 32 || s[i] >= 127) { ; } else last_char = i; } for (last_char = last_char+1; last_char < BUF_SIZE-1; ++last_char) { s[last_char] = '\0'; } return s; } char* w_getline (char s[]) { int c, i; for (i = 0; i < BUF_SIZE-1 && (c = getchar()) != EOF && c != '\n'; ++i) s[i] = c; if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return filter_line(s); } int main (void) { char line[BUF_SIZE]; printf("%s", w_getline(line)); } Exercise description "Write a program to remove trailing blanks and tabs from each line of input and to delete entirely blank tabs."
Church · 2021-03-13 04:56
>>24853 if (s[i] <= 32 || s[i] >= 127) { ; } What's this supposed to do?
Iverson · 2021-03-13 04:59
>>24854 If the character has an integer value below or equal to 32, it's not a traditional character. If the character is above or equal to 127, it isn't a traditional character either.
car · 2021-03-13 07:37
>>24853 >Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines 1. last_char as a variable name is terrible, since it doesn't hold a character, but an index. 2. for (last_char = last_char+1; last_char < BUF_SIZE-1; ++last_char) { s[last_char] = '\0'; } Here you are filling the entire length of string with NULs, that's not needed. The string ends when the parser encounters a '\0' character, so all you need to do is just end it like s[last_char+1] = '\0' 3. for (int i = 0; i < BUF_SIZE; ++i) { if (s[i] <= 32 || s[i] >= 127) { ; } else last_char = i; } Why? If you want to do something like this, just do for (int i = 0; i < BUF_SIZE; ++i) { if(s[i] > 32 && s[i] < 127) last_char = i; } 4. You are not actually removing any characters from the range of [32;127]. Imagine this array of characters (which is a string) [n][i][ ][\t][g][g][ ][y][0] Your loop goes like this: >index 0 is n, n is ASCII 110, last_char = 0, ++i (1) >index 1 is i, i is ASCII 105, last_char = 1, ++i (2) >index 2 is SPACE, SPACE is ASCII 32, last_char = 1, ++i (3) >index 3 is HT, HT is ASCII 9, last_char = 1, ++i (4) >index 4 is g, g is ASCII 103, last_char = 4, ++i(5) >index 5 is g, g is ASCII 103, last_char = 5, ++i(6) >index 6 is SPACE, SPACE is ASCII 32, last_char = 5, ++i(7) >index 7 is y, y is ASCII 121, last_char = 7, ++i(8) >index 8 is NUL, NUL is ASCII 0, last_char = 7, ++i(9) Note how the bad characters are still very much present. Even worse, loop should end at this point, but it wont. It will keep going until it reaches BUF_SIZE. Now suppose the string looked like this: [n][i][ ][\t][g][g][ ][y][0][n][i][g][o][l][a]...[s] Your resulting string will encompass the entire length from initial n to the ending s. Then you are doing this weird s[last_char+1]='\0' which as we can see easily can go out of bounds of s and result in segfault. You have already terminated s with a '\0' in the previous function, so instead of that weird ass loop in filter_line you should do int last_char_index = 0; int i; for(i = 0; s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) last_char_index = i; } Note that will still not do what you wanted, because your logic is flawed. You want to edit the line in place right? Here is how I would make your code work with minimal edits: char* filter_line (char s[]) { int i, j; for (i = j = 0; s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) s[j++] = s[i]; } s[j] = '\0'; return s; } Note that this approach still won't get you what you probably want (since you probably want the newline at the end, if present). For that we would have to modify the code a bit further. Notice that in w_getline, you broke the string on the newline, if it exists, with enough space to fit a NUL afterwards. We can use that fact to do this: [code] char* filter_line (char s[]) { int i, j; for (i = j = 0; s[i] != '\n' && s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) s[j++] = s[i]; } if (s[i] == '\n') s[j++] = s[i]; s[j] = '\0'; return s; } It should work with this. Sorry for the shoddy C code, but I haven't touched it in months (haven't really written anything in months, besides scripts). If I didn't fuarrrk up anything it should work. I tried to find my solutions from the time I did K&R but sadly I think I deleted them.
The Fin · 2021-03-13 07:41
>>24856 Aaaand I obviously had to fuarrrk up formatting. Here's fixed (hopefully): >Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines 1. last_char as a variable name is terrible, since it doesn't hold a character, but an index. 2. for (last_char = last_char+1; last_char < BUF_SIZE-1; ++last_char) { s[last_char] = '\0'; } Here you are filling the entire length of string with NULs, that's not needed. The string ends when the parser encounters a '\0' character, so all you need to do is just end it like s[last_char+1] = '\0' 3. for (int i = 0; i < BUF_SIZE; ++i) { if (s[i] <= 32 || s[i] >= 127) { ; } else last_char = i; } Why? If you want to do something like this, just do for (int i = 0; i < BUF_SIZE; ++i) { if(s[i] > 32 && s[i] < 127) last_char = i; } 4. You are not actually removing any characters from the range of [32;127]. Imagine this array of characters (which is a string) [n][i][ ][\t][g][g][ ][y][0] Your loop goes like this: >index 0 is n, n is ASCII 110, last_char = 0, ++i (1) >index 1 is i, i is ASCII 105, last_char = 1, ++i (2) >index 2 is SPACE, SPACE is ASCII 32, last_char = 1, ++i (3) >index 3 is HT, HT is ASCII 9, last_char = 1, ++i (4) >index 4 is g, g is ASCII 103, last_char = 4, ++i(5) >index 5 is g, g is ASCII 103, last_char = 5, ++i(6) >index 6 is SPACE, SPACE is ASCII 32, last_char = 5, ++i(7) >index 7 is y, y is ASCII 121, last_char = 7, ++i(8) >index 8 is NUL, NUL is ASCII 0, last_char = 7, ++i(9) Note how the bad characters are still very much present. Even worse, loop should end at this point, but it wont. It will keep going until it reaches BUF_SIZE. Now suppose the string looked like this: [n][i][ ][\t][g][g][ ][y][0][n][i][g][o][l][a]...[s] Your resulting string will encompass the entire length from initial n to the ending s. Then you are doing this weird s[last_char+1]='\0' which as we can see easily can go out of bounds of s and result in segfault. You have already terminated s with a '\0' in the previous function, so instead of that weird ass loop in filter_line you should do int last_char_index = 0; int i; for(i = 0; s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) last_char_index = i; } Note that will still not do what you wanted, because your logic is flawed. You want to edit the line in place right? Here is how I would make your code work with minimal edits: char* filter_line (char s[]) { int i, j; for (i = j = 0; s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) s[j++] = s[i]; } s[j] = '\0'; return s; } Note that this approach still won't get you what you probably want (since you probably want the newline at the end, if present). For that we would have to modify the code a bit further. Notice that in w_getline, you broke the string on the newline, if it exists, with enough space to fit a NUL afterwards. We can use that fact to do this: char* filter_line (char s[]) { int i, j; for (i = j = 0; s[i] != '\n' && s[i] != '\0'; ++i) { if(s[i] > 32 && s[i] < 127) s[j++] = s[i]; } if (s[i] == '\n') s[j++] = s[i]; s[j] = '\0'; return s; } It should work with this. Sorry for the shoddy C code, but I haven't touched it in months (haven't really written anything in months, besides scripts). If I didn't fuarrrk up anything it should work. I tried to find my solutions from the time I did K&R but sadly I think I deleted them.
sizeof · 2021-03-13 07:46
>>24857 Oh fuarrrk, I forgot about deleting entirely blank lines. For that you can just do something like: if (c == '\n' && i != 0) { s[i] = c; ++i; } in w_getline. Oh god, you must think I'm a clown now.
Chan Siu Ming · 2021-03-13 08:09
>>24858 Also here is the full program if you get lost https://bpa.st/NTAA
Unidentified · 2021-03-13 08:13
>>24859 ...also #include <string.h> #include <unistd.h> is redundant, since you are not using anything from these libraries. Oh sweet jesus please, I'm not spamming, please don't hit me.
The Phantom Phreak · 2021-03-13 19:15
>>24852 > handmade hero "intro to c on windows"? Thanks but no, it was more an academic source as I recall. I remember the background color of the page was grey...
protected · 2021-03-14 08:02
>>24856 >>24857 >>24858 >>24859 >>24860 Thank you Lainon, I really appreciate this. It's funny how hard it is to see your own logic errors sometimes. K&R is my first foray into programming, so detailed posts like these are really helpful.
Masami Eiri · 2021-03-14 08:07
>>24882 Oh, and by the variable named "last_char" I meant last character encountered. It made sense to me, but I can see how it might not be that descriptive
Sabo Engle · 2021-03-15 10:10
Why would I want to program in C though? If I did that I wouldn't become an MIT Computer Scientist.
Sipho Nkosi · 2021-03-15 10:18
>>24890 C, and memory management is fun, that's why! I mostly like messing with the UNIX\Linux system stuff, and find C to be the most interesting language for that.
Jens Hansen · 2021-03-15 10:53
>>24891 That's exactly why I'm currently learning C. I'm interested in UNIX.
queue · 2021-03-23 12:29
>>24890 >>24891 Python is nice to write, but is like : problem.py import solution def pbSolver(pb): return solution(pn)
Switch · 2021-03-23 12:30
>>25040 I managed to fuarrrk it up anyway lol return solution(pb)
Ivan Petrov · 2021-03-25 22:39
>>24826 Is it this one? https://matt.sh/howto-c Starts off with the same phrase, has lots of info about modern C.
Lady Jessica · 2021-03-25 23:57
>>24826 >https://matt.sh/howto-c Awesome resource, thanks for this.
↑ · 2021-03-27 09:24
>Check out "Expert C Programming: Deep C Secrets" by Peter van der Linden. He does an exceptional job of bridging the gap between high/low-level thought processes. Thanks for the suggestion. I'm reading it right now and I like it, I'm learning a lot. I also found through a link in the previous thread which I am enjoying as well: https://beej.us/guide/bgc/html/ >I've never met a single programmer who could explain pointers beyond "hurr it points" which is horrible for a beginner. Pointers make more sense to me if I completely replace the word 'pointer' with the word 'address'.
quote · 2021-03-27 11:38
>>24890 >not just writing lambda calculus directly
Apoc · 2021-03-31 11:44
I love C. But I would love it even more if it was strongly typed and the compiler watched your back better. Also undefined behaviour is like kicking dead whales down the beach.
Yuki Nagato · 2021-03-31 13:54
>>25076 >>25077 YES! Thanks a lot fren.
t · 2021-03-31 14:22
>>25181 No problem, happy to help.
if · 2021-03-31 18:56
Any good examples of any "popular" software written exclusively in C?
Aristóteles Amadópulus · 2021-03-31 19:27
>>25188 All of open source basically
Batou · 2021-03-31 20:01
>>25188 http://bxr.su/OpenBSD/
Undisclosed · 2021-04-01 08:45
>>25188 >Any good examples of any "popular" software written exclusively in C? nginx
Tequila · 2021-05-16 18:47
I'm on manjaro and set up my C environment. How do I install libraries or check which ones are installed? >>25093 what do you do if you are talking about the address of the pointer? as opposed to the address in the pointer
SHODAN · 2021-05-16 18:52
>>25188 Linux, FreeBSD, OpenBSD, NetBSD, DragonflyBSD, Perl, Python, Ruby, Apache HTTPd, nginx, lighttpd, PostgreSQL
vi-user · 2021-05-16 19:10
>>25856 >How do I install libraries or check which ones are installed? pacman -S lib* or whatever lib you need more often than not you'll find yourself implementing features by hand rather than using a lib, e.g. using raw sockets instead of libcurl
Lord Nikon · 2021-05-17 15:35
Just trying to give a small contribution to this thread, well its not really just about C but it useful at least in C and C++. >Calling function debug time https://sourceware.org/gdb/onlinedocs/gdb/Calling.html It can be very helpful if you want to just call a function without recompiling the code and reestarting the debug from scratch, specially if the code take forever to reach the problem. I learned about this because I was debugging a C++ program which crashed after processing my data, then I had a specific function to save vector of structs in a plaint text file, but this function cannot just receive a literal string as a filename, it receive a std::string and the vector itself... thus i was unable to call it but I found a workaround, because with the CALL in gdb we can call even malloc and it will allocate memory and return the pointer for us. Then I prepared the following function in my .gdbinit define newstr set $str = (std::string *) malloc(sizeof(std::string)) call $str->_M_append ($arg0, sizeof($arg0)-1) end Its pretty cool, even that my usage was in C++, we can benefit from this in C in some cases too, here is an example of output using my defined function. (gdb) newstr "present day, present time" $1 = (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > &) @0x7ffff7a9bb60: {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x41aeb0 "present day, present time"}, _M_string_length = 25, { _M_local_buf = "\031", '\000' <repeats 14 times>, _M_allocated_capacity = 25}} As you can see, I got string object just created for my usage. I hope you all enjoy this little tip.
Batou · 2021-05-18 00:20
>>25857 Akchullllly Linux is also wirtten in assembly language for several different architectures, and the BSDs (as whole OSes as they are) are partly written in /bin/sh and other languages. OpenBSD uses Perl for many utilities. The NeTBSD kernel is extensible with lua. And, while a bit of a circular argument, every language (that's worth using) is partly written in (a smaller version of) itself. Now you could say /bin/sh, awk, Lua, etc are all written in C so the OS is ultimately all written in C. A corollary is that either C is the bedrock upon which all software is ultimately written, or, on the other hand, C is like the Internet Explorer of languages, and so only good for making other languages. Either way, it's certainly an important language.
Knuth · 2021-05-18 01:17
>>25875 >IE i don't like the comparison because the reason why IE is necessary have more to do with Microsoft's monopoly than IE per se, but i c what u mean.
Netrunner · 2021-05-19 23:38
I'm learning C as my first language, since I heard that it helps you to understand how the code intereacts with the computer and that it will teach me useful practices that will help me become a better programmer. Do you have any tips or advice for a newbie?
alexandra · 2021-05-19 23:53
>>25884 understand that everyone is bad at programming, and nobody is good at programming. learn things as well as you can but there will always be something you don't fully understand. computers are just too big. do what you do for fun, and try not to lose sight of the "art" part of coding (finding the best solution and making beautiful code and whatever). not C specific just good to know as a beginner. stuff I wish I had known
Morpheus · 2021-05-20 12:18
>>25885 Thanks for the general advice. I really appreciate it. It's good to know that it's an overall journey and that no one is completely perfect at it.
Hopper · 2021-05-20 20:47
>>25884 >Do you have any tips or advice for a newbie? Handle strings very carefully. Especially for anything exposed to a network. Seriously, it can't be stressed enough. Mishandling a string in C is one of the easiest mistakes to make, with some of the most severe consequences.
Colmerauer · 2021-05-20 22:06
>>25884 Don't be discouraged by the naysayers who will tell you C is BAD. Realize no language can ever be perfect, C clearly has it's faults and it's strengths, and that it thrives in its domain but it simply cannot be all things to all people nor it should. Don't get too attached to one way of thinking and have fun. Remember that after all the purpose of programming is to write computer programs and not to bask in ideology. Learn to read assembly language for your architecture. Learn how malloc is implemented, the memory layout of a program, the behaviour of the stack, etc, etc. The language is much more than the syntax and the standard library.
Zero Cool · 2021-05-23 15:26
>>25884 You can learn a lot from C no doubt, but other places as well. I am a terrible programmer and i am still in the beginner phase basically after like 15 years of casually trying and failing. I enjoy the reading about it more than the doing I guess. But I've had a few epiphany moments, and one of them would be reading the Atari 2600 programming guide. You realize that the limitations of computers never change. The same limitations then are the same as now. It's not noticeable now usually, but they are there. And you kind of get an idea about how hardware works too. And the reason why somethings can be implemented in hardware instead of using hardware. the Forth language, was the one I first really understood. And was like damn I get it now. And then comparing it to Python, I learned even more about some confusing topics in Python and similar languages. And C is interesting too. Like I said I am not a good programmer, and my advice should be approached with skepticism, but you can learn a lot from other things besides C. So don't become too married to it if it just isn't working for you.
Cowboy · 2021-05-25 21:01
>>25885 >understand that everyone is bad at programming, and nobody is good at programming. No, you're supposed to be an insufferable autist and denigrate anyone lacking even a single piece of trivia.
Random · 2021-05-29 17:39
Making pong in terminal, Why does my code cause errors? I get an : ‘paddle’ is a pointer; did you mean to use ‘->’? I don't understand this, because the x and y are not pointers. I still get the erroor if I dereference paddle and .y or .x. and my macros give errors too. #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <sys/ioctl.h> #include <unistd.h> struct winsize screen; #define h screen.ws_row #define w screen.ws_col typedef struct paddle { int x; int y; int size; } paddle; typedef struct ball { int x; int y; } ball; ball b = {10, 10}; paddle paddle1 = {2, h/2}; #define move(x y) printf("\033[%i;%iH", x, y) void draw_paddle(paddle* paddle){ for(int i = 0; i == paddle.size; i + 1){ move(paddle.x, paddle.y + i); printf("#"); } }
Batou · 2021-05-29 18:13
>>26003 >‘paddle’ is a pointer; did you mean to use ‘->’? The "paddle" argument to draw_paddle(paddle* paddle) is a pointer. When you use . you access the member of a struct. However, to reference the members of a pointer to a struct, you have to dereference the pointer (as in (*paddle).x). This is kind of tiring to write, so C includes special syntax for doing this: the -> accessor. So (*paddle).x is the same as paddle->x.
Molly Millions · 2021-05-29 18:50
>>26003 did you write this code with several bad practices for brevity or are you unaware of them?
XERXES · 2021-05-29 20:11
>>26004 I see. how would you access x if x were a pointer, like this (see code)? This is what I thought -> was for. typedef struct paddle { int* x; int *y; int size; } paddle; >>26006 I probably don't need the headers, but I am trying things out and might as well keep them there so I can experiment. >why not const instead? I was thinking that screen.ws_row was a constant/variable with a name I didn't like, so I am trying to use a macro to rename it. But if I declared it a constant it would just use more memory. >why not capitalize constants like everyone else? what constant. >why not avoid using single-letter constants? h and w are descriptive as are x and y, it is obvious what they mean at least to me. >>26007 probably unaware...
Cutter · 2021-05-29 20:16
>>26006 >#define move(x y) printf("\033[%i;%iH", x, y) > why not write a regular function instead? since controlling a terminal is all about printing control characters, I figured it would be better to use one function call, instead of 2. > >struct winsize screen; > >ball b = {10, 10}; > >paddle paddle1 = {2, h/2}; > why not use local variables instead of globals? I figured in the realm of pong these probably make sense to be global.
quote · 2021-05-29 21:46
>>26008 >I see. how would you access x if x were a pointer, like this (see code)? This is what I thought -> was for. To access the pointer you do paddle.x If you want the value at the pointer x (aka, you want to dereference it) you do *paddle.x Why did you think -> meant accessing the pointer value of a struct? Code like that won't even compile.
Technician · 2021-05-30 00:10
>>26013 So to clarify I thought that . was for the member and that if the member was a pointer and you wanted to dereference that you need to -> So by my logic for my question >>26008 I thought this should make sense *(paddle)->x Basically a double dereferenceing
Emmanuel · 2021-05-30 00:26
>>26003 Prefer function inlining to using function-like macros.
Cypher · 2021-05-30 00:53
>>26016 Never heard of that seems like a great tip. Thanks.
Zuse · 2021-05-30 03:25
>>26008 >>26009 >But if I declared it a constant it would just use more memory. no it doesn't. maybe if you were using gcc or msvc back in the 90s. https://en.wikipedia.org/wiki/Constant_folding all major compilers (gcc, clang, msvc) will optimize that away. consts are easier to debug, compilers can actually catch errors on them, macros are a really hacky thing that should be used as last resort. >I figured it would be better to use one function call, instead of 2. compiler will inline it for you. it's 2021, not 1999. as linus torvalds says, stop thinking that you will do a better job than the compiler, they've come a long way. you're using a modern compiler i'm assuming, not an n64 sdk c compiler from the mid 90s. >h and w are descriptive as are x and y you don't want to steal single letter variables like "h" and "w" from an entire source file with globals or macros. very bad habit. what if you wanted to make a function that declares a local variable or parameter with one of those letters? >I figured in the realm of pong these probably make sense to be global. global namespace pollution, no compiler optimization ( https://stackoverflow.com/questions/11977316/memory-allocation-for-global-and-local-variables ), no control over when the memory for those variables gets allocated (globals are all allocated at startup), there is no reason to make them global, again another feature that's last resort.
null · 2021-05-30 18:16
>>26018 Where would you put the globals then?
Koos van der Merwe · 2021-05-30 20:42
>>26021 Name them relevantly, because it'll cause trouble if you try to use globals from imported header files only to immediately shadow them and lose access. A few more seconds typing the name (or just using autocompletion) won't kill you, and it'll save you a bunch of trouble later.
Knuth · 2021-05-30 20:45
>>26021 >>26022 https://en.cppreference.com/w/c/language/storage_duration This may also be of interest
Neuromancer · 2021-05-30 20:50
>>26021 finish your program first also you should be using ncurses.h https://ostechnix.com/how-to-install-ncurses-library-in-linux/ sudo apt-get install libncurses5-dev all implementations of pong for terminal that i can see seem to be using its functions for clearing (clear), drawing (refresh), getting dimensions of screen (getmaxyx) you should be able to do everything with just ncurses.h and unistd.h (just for usleep), you don't need any of those other libraries
Zuse · 2021-05-30 21:12
>>26024 should also mention ncurses.h already includes stdio.h which you'd use for mvprintw and printf to do all the formatting/printing. also you'd use getch from ncurses.h for keypresses.
Y.T · 2021-05-31 01:09
>>26018 So how do I change #define h screen.ws_row to something like this. H = screen.ws_row; I get the error "expression must have a constant value"
Splicer · 2021-05-31 06:00
>>26029 write your main function first, stop making all these weird globals and macros. #include <sys/ioctl.h> #include <stdio.h> int main(void) { struct winsize ws; ioctl(0, TIOCGWINSZ, &ws); printf("rows: %d\n", ws.ws_row); printf("cols: %d\n", ws.ws_col); return 0; } only after filling in your winsize struct using ioctl would it make sense to make a couple variables as shorthand aliases if you need them for convenience. #include <sys/ioctl.h> #include <stdio.h> int main(void) { struct winsize ws; ioctl(0, TIOCGWINSZ, &ws); const unsigned short h = ws.ws_row; const unsigned short w = ws.ws_col; printf("rows: %d\n", h); printf("cols: %d\n", w); return 0; } and no, these two variables won't be using extra memory, the compiler should be smart enough to see they are redundant, don't try to be clever with #define or whatever. ioctl is a generic system call, in this case being used for terminal i/o. to specify what you want this system call to do, in the second argument you pass in one of these numbers (constants) as an option: https://code.woboq.org/gcc/include/asm-generic/ioctls.h.html TIOCSWINSZ is aliased to a constant number and is a weird abbreviation that stands for "tell ioctl to get window size" or something like that (that's crappy old 70s unix design for you). third argument of ioctl is to pass an address to the buffer (your winsize struct) on where to store this window size data you just requested.
sizeof · 2021-06-01 06:09
>>24824 what design philosophy do you guys follow if any? the suckless philosophy seems decent. also is there any comprehensive guide on gcc optimizations? what they do and when to use which optimizations etc.
Pris · 2021-06-04 00:45
>>26050 >the suckless philosophy seems decent Is suckless really a good design philosophy? It feels like a vapid restatement of the Unix philosophy with more fluff around it. That also reminds me back to the time when ST (Simple Terminal) used XLFD instead of XFT for fonts. In the name of simplicity they made the end user have to deal with legacy cruft. Some of that cruft being an abhorrent abomination that many wish had died off years ago. They talk about praising code quality but come on, if you are building an application and using legacy technologies can you really say it is a quality product? I am aware that this is not longer the case and ST supports XFT but it seems silly they ever pushed the idea of XLFDs being simple or elegant. As for good design philosophies, there are a lot of different approaches and it heavily is centered around the project you are going to be creating, how long you want to maintain it, if you want others to ever contribute, etc., there is no one size fits all. I would suggest you look into LuaJIT and the story of Mike Pall. Mike Pall has always been at the forefront of LuaJIT. Every contribution is meticulously reviewed by him. He is also the person to make the important architecture decisions. Effectively this causes him to be quite dexterous in refactoring. Pall can effectively rewrite parts of LuaJIT. In fact he has done it multiple times, check the change log. Rewrites are typically seen as ineffectual when the project is big but because Pall is so integrated with his project, when he deems a rewrite is needed of some parts, he can do it. That being said there is a downside to this, finding people to replace him is nearly impossible. Once Pall dies, LuaJIT dies with him. The code base is just not designed in a way that it allows independent uncollaborated contribution. However for what LuaJIT it is and does, it works out fine.
Koos van der Merwe · 2021-06-04 21:32
>>26050 I try to keep things simple, but also avoid as much boilerplate as I can. At work I err on the side of simplicity, but on personal projects I let out the preprocessor hacking I could never convince a manager to ship. >>26085 Suckless dweebs don't know what they want except to emulate a caricature of UNIX grognards. emacs is one of the most maximalist program in the *NIX canon, and yet it's also the most popular. Suckless programs don't do one thing and do it well, they do as little as they can.
Trinity · 2021-06-16 22:09
>>25076 I really can't understand why he suggests always using stdint types even when the size of the variable is not that relevant. If I just need, say, a counter for the number of reflections of a ray in a raytracer, what would the advantage of using int64_t over int be? What do you Lainons think, am I missing something?
Void · 2021-06-16 23:10
>>26273 imo most of the benefits are theoretical, but they are worth considering. clarity: it is, in my opinion at least, easier to reason about what you're getting when you specify "uint64_t" vs "unsigned long long" (as evidenced by your confusion regarding "int" being 64 bit... it's usually 32 bit. as an aside, "long int" and "int" typically the same thing). just writing "int" might seem convenient, but most of the time you want a bit more specificity than that. this specificity can, in principle, be achieved with the standard short/long/unsigned/etc. but they're somewhat cumbersome compared to just saying how long you want the thing to be. so what about the cases where you do just want a 32 bit signed int? well, if you're using stdint types for everything else, it's probably a good idea for consistency's sake to use int32_t instead of int as well. portability: now, technically int32_t doesn't actually guarantee a 32 bit integer but at least there isn't a strong precedent for it being something other than 32 bits. ints on the other hand are completely dependent on the compiler. the practical implications of this are probably not as severe as it sounds, because all the big compilers for 32 and 64 bit x86 and ARM use 32 bit ints, but it's still something to think about. additionally, you can easily redefine the stdint types at compile time by simply including a different header (because they're just macros) but you can't necessarily do the same for builtin types. for some additional perspective, many libraries define their own integer type macros, and usually they're just typedefs for builtin or stdint types. if you end up working on a large codebase, this is probably what you'll do. i've also seen codebases where stdint types are used for data members in structs and such, but not used for temporary local variables like loop indices, so a mixed approach evidently has some benefit to some people. tl;dr i would recommend using stdint types in most situations but they aren't entirely necessary. for situations where the size of the integer truly doesn't matter, it just comes down to how much you value consistency. frankly, if you're going to get pedantic about something, it's probably more important to use size_t, ssize_t, off_t, etc. correctly. i would suggest just looking at existing codebases to see how they deal with their integers.
Pris · 2021-06-17 09:35
>>26275 Thank you for your answer. I still have a lot to learn, so reading other people's opinions is very helpful. I understand what you say about portability and wanting to be specific in many cases. For example, if I am transmitting data over a network and I need to have control about the size of variables, of course I would use stdint types. However, >as evidenced by your confusion regarding "int" being 64 bit... it's usually 32 bit My point was that I don't see why I should know if my variable is 32 or 64 bits in a case similar to what I was describing, because I simply need an integer value to count things: so why not use the most natural representation of an integer for the processor I'm compiling on?
Liet Kynes · 2021-06-18 15:19
>>26276 depends how high you count
Void · 2021-06-20 05:42
What do you guys think of the extensions provided by gcc/clang? Obviously if you have to write ISO compliant code then you can't use them, but since I've been reading what clang/gcc provide some of them are incredibly useful if you need very specific behavior. Personally, __builtin_choose_expr, compound statements, and typeof are my favorite as they let you do pretty neat things with macros. Transparent unions and union casts also seem pretty useful if you want to implement polymorphism without resorting to void* and throwing away type checking. >>24890 >machine learning people don't want to program unsurprising >>25872 neat
Terzibashjian · 2021-06-20 06:12
>>26315 isn't portability one of the main strengths of C, and wouldn't using compiler extension throw that away? why not use standardised c++ instead? im still a noob, so those are genuine questions not passive aggressive suggestions.
Jane Doe · 2021-06-20 07:58
>>26315 __attribute__((cleanup)) is really cool (destructors for variables that get called when the variable goes out of scope.
Pris · 2021-06-20 17:04
>>26316 It is, but it depends on what you're writing and how it's going to be delivered. For example, if you're writing a library then you don't want to use compiler specific extensions because you want it to be compatible with as many platforms/compilers as possible. On the other hand, if you're writing something that gets delivered directly to the consumer/customer as a binary, it doesn't really matter unless you need to port it in the future to other platforms/compilers. The good thing is that gcc/clang largely support each others feature set and have support for most the major architectures (x86, ARM, PowerPC) and a significant number of the smaller ones which makes portability less of an issue when considering specific compiler extensions nowadays. Depending on what you're writing you may also just need to leverage undefined/unspecified behavior where you can only guarantee correct code output on a specific compiler version + architecture + settings. If you can avoid writing unportable code then you should, but sometimes it's unavoidable.
Dozer · 2021-06-24 17:35
Doing only simple embedded-related things in C made me completely oblivious to the fact that it is a fuarrrking nightmare to program in. I feel even more stupid that I have been actually defending this crap, but I guess the embarassment and ridiculous amount of time is what is needed for scraps of coding proficiency in this language. I am going insane...
Aristóteles Amadópulus · 2021-06-24 22:14
>>26372 Nevermind, I played some basketball and after that I found a nice solution. Learning process is a very painful one.
The Phantom Phreak · 2021-06-25 16:16
>>26315 I like GCC's __attribute__((vector_size())) for vector types, since the alternative of using Intel's vector types is hardly any more portable. Clang's __attribute__((overloadable)) is also pretty nifty for overloading functions like in C++, but I'm not sure whether that's an appropriate feature for C. >>26318 That attribute is very useful, but to me it doesn't feel like something that should be in a language like C. If you try to emulate RAII using __atrribute__((cleanup)), then you're going to have a bad time when it comes to dynamically allocated memory, since the attribute only works properly with stack-allocated variables. I don't think most C programmers would be particularly delighted to have to manage that kind of hidden control flow. It is nice if you want to use defer statements, though, since they can be used to emulate that.
Pris · 2021-06-28 19:32
I tried programming C in a windows environment, and I realized it's much easier to do in Linux. I'm a beginner to all this (programming), so maybe that was the issue. But I'm still sticking with linux. Right now, I'm currently reading Beej's guide (https://beej.us/guide/bgc/html/) and watching Harvard's CS50. I'm probably gonna read the original K&R as well once I'm finished.
Delilah · 2021-06-28 20:31
>>26428 > and I realized it's much easier to do in Linux. curious, in what way? sounds plausible, but it's been too long since I've programmed on windows to remember why.
Leto Atreides I · 2021-06-30 13:37
>>26430 It was kind of difficult for me to set up codeblocks an learn how to configure it. I eventually got it, but I decided to move on to linux by then. All I have to do in linux is write the program in a text editor, and then compile and run it in the terminal. Easy as pie. Though, it probably will get difficult later on when I get errors and stuff.
Roger Pollack · 2021-07-03 15:54
let's say you have a function it returns an int and you want to use that int int foo = bar(); foo is a memory address the compiler put aside for us. but what if you don't want the return value? you just run the function but no assignment. bar(); where does the value get returned to?
Milner · 2021-07-03 18:26
>>26515 If the compiler isn't clever enough to just optimize it away, return in C is implemented out of asm's ret. ret <n> will push n bytes onto the caller's stack or a return register. On x86 machines and if the compiler doesn't notice the unused value or can't optimize the ret away, bar(); will put it's return value into RAX as normal.
Naomi Nascimento · 2021-07-03 19:45
>>26517 Is it possible for the compiler to remove the ret unless the function is inlined? What you describe is what I thought the function always does regardless of where the caller wants to put the return value.
Joe Bloggs · 2021-07-06 00:23
>>26515 It depends on optimization settings and whether the function was inlined. If the function wasn't inlined and optimization is disabled then you execute a call instruction to the entry point of bar(), execute the code, and the return value is put wherever the ABI/calling convention specifies (on x86 the value is returned in eax/rax, on ARM it's r0, etc.). If optimization is enabled and all of your calls to foo() discard the value (this depends on other factors) then foo's return value may be optimized away (i.e. portions of foo() or all of foo() may be removed, depends on if there's side effects). If it gets inlined, the compiler can make the determination at different call sites, i.e. it can optimize out the return when the value isn't used or keep the instructions to compute the value and put the value in the return register if it is, depending on the call site. Also if a function returns a constant value, or is pure (a function of only the argument, with no side effects) (and the compiler decides it's simple enough, depends on optimization settings), then the values at specific call sites may be computed at compile time and inserted into the assembly as constants.
Arisu Mizuki · 2021-07-22 13:07
>>26515 The function returns the value in a register (some variant the "a" register if you're using the x86 SysV ABI). It would only then get copied to a memory location if the caller chooses to do so. On certain ABIs on some architectures, it could be possible that the function instead returns the value by placing it at the top of the stack (between the caller and callee's stack frames), and then the caller could copy it to another memory location. Of course, all of that goes out the window if the compiler wants to optimize those functions. Then it could do whatever it wants, as long as it gets the job done. >>26518 >Is it possible for the compiler to remove the ret unless the function is inlined? The compiler has to have a way of going from the instructions of the caller to the instructions of the callee. The compiler's favorite way to do this is by inlining, since then it just works without any jumps. For larger functions, or ones that are called too frequently, this is suboptimal because accessing nonlocal areas of memory is generally much slower than a couple jump instructions. Even in those cases, the compiler is free to change the behavior of the function (e.g., skip putting the return value in the right place, as long as all callers ignore the return value, or removing an if statement that it can reason will always been skipped.) The only case where the compiler can't optimize the functions like that is when the function and the caller are in separate compilation units (without link-time optimization). In that case, the compiler has to follow the ABI and can't really make any assumptions about what the caller actually needs the function to do (as opposed to what the function promises to do). Sometimes the compiler will make two copies of a function: one that's used internally and can be optimized more, and one "correct" version that gets exported as a symbol for any other compilation units that get linked to it.
Spooky · 2021-07-22 16:46
might get a job writing embedded C soon, what am I in for?
nibble · 2021-07-22 23:30
>>26851 depends what kind of embedded it is you know - working with programming humidity regulators for a warehouse is different sort of work than porting Linux to some custom ARM chip which is different from programming firmware for fighter jet planes which is different from programming some firmware for satellites which is different from programming firmware for car engines and so on and so on also you can have a job "in embedded" all all you do is "embedded" webdevelopment for some soykafty interface to some soykafty app for "smart TV/car video player" etc.
drop · 2021-07-22 23:39
>>24824 Is C ever going to stop being used (before the civilization falls)? Are there any advantages of learning C over other languages? Why do people like the syntax? Isn't the difficulty level of C programming the reason garbage like Electron becomes more and more popular? Is there any excuse for the pointer syntax?
Agent Smith · 2021-07-23 05:54
>>26855 >Are there any advantages of learning C over other languages? mature, minimal and high performance. does depend on what you're doing though, may not be the suitable option. >Why do people like the syntax? because it's rather simple. >Isn't the difficulty level of C programming the reason garbage like Electron becomes more and more popular? i don't think C ever even competed in that field to be honest. electron is popular due to being cross platform, easy entry helps too I guess.
Gyula Kovacs · 2021-07-25 19:27
>>26854 good point. its something to do with robot firmware but im paranoid to be more specific and i dont know where exactly my code will go. i guess i'll found out more later.
Cypher · 2021-07-25 23:38
>>26428 >>26454 >I tried programming C in a windows environment, and I realized it's much easier to do in Linux. >It was kind of difficult for me to set up codeblocks an learn how to configure it. >All I have to do in linux is write the program in a text editor, and then compile and run it in the terminal. Easy as pie. It can be just as easy on Windows by installing MinGW and adding the bin directory to your Windows PATH environment variable, then you can write the program in notepad or notepad++ and compile and run it in cmd. http://www.codebind.com/cprogramming/install-mingw-windows-10-gcc/
Dox · 2021-09-03 00:56
>>26880 That original comment is weird since codeblocks comes with MinGW preconfigured. You literaly just click build and run.
Anonymous · 2021-09-07 04:10
Hello /g/entlemen, I'm trying to write a multithreaded program at the moment using pthreads. I need threads to communicate with each other using a "manager" thread that passes communication around. Could someone confirm that this is indeed a good idea: Give the first function in each thread 32 bytes of memory. Split memory into 2 16 byte sections. First section is for thread to manager communication, second section is for manager to thread communication. The threads won't be communicating often so this shouldn't be a problem. My only concern is if I have to communicate something more substantial like a struct.
Guthrie · 2021-09-07 06:20
>>27428 If you need to share a large amount of data between threads, you can just make sure that no thread is writing to that block of data, then any number of threads can be reading it at the same time. Constant data can be freely shared. So just have that data be of a constant value while other things are accessing it.
XERXES · 2021-09-07 07:50
>>27428 you could implement pipe like functionality if you need larger stuff - buffered input/output. writing data to a location and if there isn't enough space waiting till the other thread has emptied the buffer by reading the data.
Zero Cool · 2021-09-08 12:05
>>26273 >>26275 if you're going to be using stdints please use least*_t
Tinkerer · 2021-09-19 11:09
[blog] A year ago I switched from c++ to c looking for simplicity. In a way a found what I wanted, but I also ended up recreating some functionality like runtime polymorphism with vtables and such. I don't think that would be a problem if the preprocessor weren't unnecessarily crippled. [/blog] Recently I started to tinker with the idea of developing a custom preprocessor with some extensions, for example: - multiline macros allowing directives inside - some way to omit the variable arguments After some research I found https://github.com/facebookresearch/CParser , but I still want to do may own implementation in C. So, what preprocesor extensions do you think that C should have? what extensions you think it shouldn't? For example, I'm also considering the possibility of some sort of "pattern matching macros" to implement custom operators o syntactic sugar.
Incognito · 2021-09-19 13:50
>>27520 Guy I talked to on IRC made a pragma which created function prototypes from an implementation file, eliminating the need for header files. That could be useful for your preprocessor.
Technician · 2021-09-19 20:12
>>27520 I wonder how feasible it would be to use some form of Lisp as a macro language for C.
Lady 3Jane.. · 2021-09-21 00:09
>>27520 c preprocessor macro arguments don't support chunks of arbitrary text/code. this is very annoying, made it more difficult than necessary to make custom iterators in c macros. a block of code/text surrounded by {` `} can be treated as a single macro argument. that is "open curly bracket" "grave accent" & "grave accent" "close curly bracket" you could also do #begin #end or something but {` `} is shorter & easier to read. >>27526 c preprocessor just pastes and substitutes text. you could use any programming language for this, so lisp is feasible too. the preprocessor is just a language that exists outside of c that modifies the text/code before it is processed as c code at all. can have completely different syntax to c just needs to output valid c in the end. it's like php tags <?php ... ?>
typedef · 2021-09-28 00:18
>>27520 I would completely change the syntax and support recursive macros and just go full FP >>27545 A non standard way to do this is gcc/clangs compound statements I believe
Wintermute · 2021-10-07 18:38
anyone has a good print of ISO C89 standard? the pdf i got off of zlib is kinda blurry.
Roger Pollack · 2021-10-08 06:28
checdk out my gol in c :DDDDD https://0x0.st/-Ei7.c
Motoko Kusanagi · 2021-10-10 10:56
>>27817 I vote for more i++
Tinkerer · 2021-10-10 15:48
Hello again, I'm the guy writting a C preprocessor to add new features. Now I have an almost completely working standard preprocessor... I think. I have to test it more and then start to add non-standard features. >>27522 This would require parsing the C code to extract the functions declarations. Personally I like the headers files because they are a nice place to have the interface of a module and some documentation. >>27526 Adding some Lisp-like functionality could be interesting. The __VA_ARG__ are in a way lists and some operators to manipulate them like that could be useful. >>27545 Having arbitrary text as arguments would require running the tokenizer on the result. An interesting idea would be to have an inverse of the hash operator: going from text to a sequence of tokens. But... could you show me an example where this would be useful? >c preprocessor just pastes and substitutes text I though as much at first, but then I had to implement a C expression parser to process the #if directive. Now, being able to use this in other directives could be interesting. >>27710 Using a completely different language as preprocessor can be interesting, but I want to make something that can be recognized as "almost-C" by other C programmers and used without a large learning barrier. >>27814 I'm using the C11 standard you can get from here: http://www.open-std.org/JTC1/SC22/WG14/www/standards Not sure where to get C89 one.
() · 2021-10-10 19:58
>>27890 >C11 standard very bloated... like 600 ish pages, same with c99... c89 on the other hand is like 220 pages.
nil · 2021-10-11 17:31
>>27916 It's definitely bloated. C is a language full of hidden pitfalls and traps hiding behind every corner.
Agent Smith · 2021-10-11 19:04
>>27916 >Features =/= bloat what useful features does c99 bring? VLAs are considered harmful and made optional in c11. stdints is convenience, nothing too important, same with being able to declare variable inside for loop.
Anamika · 2021-10-11 19:36
>>27919 A standard library.
The Plague · 2021-10-11 19:38
>>27920 I am talking about the language, not stdlib.
word · 2021-10-12 07:16
>>27919 not him, but flexible arrays are the first thing that come to mind.
Gyula Kovacs · 2021-10-13 17:13
>>27919 struct OptArgs { int arg1, arg2; const char * arg3; ... }; static inline int func(OptArgs A) { ... return A.arg1 + A.arg2; } #define func(...) func((struct OptArgs){ __VA_ARGS__ }) // Example calls func(12) func(12, 34) func(.arg3="txt")
The Oracle · 2021-10-14 02:06
What do you think about C23? I am glad about __has_include and typeof , but worried about #include-binary . It sound pretty good, but heard that it was too complicated and caused ediannes problems. Do you think they will be able to be resolved?
Judge Fang · 2021-10-15 08:08
>>27979 >What do you think about C23? pic related
renames · 2021-10-15 08:11
>>28009 oops, forgot the pic. don't think there's much reason to think about it until it's implemented. if its good maybe i'll use it, otherwise c89 works fine.
The Plague · 2021-10-15 10:22
>What do you think about C23? I'll wait until its ready in 6-8 years once the major compilers actually manage to implement it, which some of them still have trouble doing with C17.
The Oracle · 2021-10-16 04:06
>Do not use C99 bool types (stick to integer types). http://suckless.org/coding_style/ why is this? what's wrong with bool.
progn · 2021-10-16 18:30
>>27979 >What do you think about C23? obvs. C99>C89>C23>C17>C11
Gyula Kovacs · 2021-10-16 20:30
>>28031 >why is this? Senseless purism, probably.
Demeere · 2021-10-16 21:09
>>28031 Because bools are implemented in kinda retarded way where they have random-ass size.
William Holtzer · 2021-10-19 02:44
>>28044 if the intention was to save size, wouldn't they use char instead of int ?
Haruyoshi · 2021-10-19 07:37
>>28064 No. I would use fixed width integer types, such as int8_t. see, https://en.cppreference.com/w/c/types/integer and compile the program with -Os
Leto Atreides I · 2021-10-19 07:42
>>28066 >I would use fixed width integer types, such as int8_t. suckless doesn't use stdint.h , so if they wanted to save space they would use char
Nell · 2021-10-25 10:14
been looking into data oriented design recently. any cool tool too analyze memory access, cache miss etc? preferably Free (as in freedom) and cli/terminal based.
if · 2021-10-25 19:33
gonna learn c, newbie, which book should I read? The C Programming Language?
Drifter · 2021-10-25 20:48
>>28221 new to programming completely? if so then I'd honestly start with a small scripting language instead. It's much easier when you know basic programming concepts such as variables, types, arguments, loops etc. otherwise yes, K&R is still very good resource to learn C, even today. some people will say it's "outdated" but the C language hasn't changed much. the very little that it did change, you can pick it up quite trivially if you know ANSI C.
Vasya Pupkin · 2021-10-25 21:38
>>28222 thanks, I know some basic programming concepts like variables, functions and loops etc, but have never finished a small project :( I will give K&R a try
let · 2021-10-25 22:05
>>28223 K&R is a good second book. I'd recommend C Programming: A Modern Approach by K. N. King first as it is targeted towards novice programmers and has been a great experience for me personally in learning C. The author also has a nice collection of secondary C books worth reading on his website which includes K&R C http://knking.com/recbooks/c.html. K&R C not only references a commonly outdated version of C but is designed for people who already understand advanced programming concepts and have experience with programming in other languages. The book I referenced in the previous paragraph is written with C99 in mind, which is not too different from C11 and C17 and is still used for massive projects like the Linux kernel and the Vulkan API, not to mention has overall great compiler support, which cannot be said for newer versions of C as they usually aren't fully implemented yet except in the most mainstream compilers.
Zhora · 2021-10-25 22:36
>>28224 Thanks. After reading some pages, I think the book you recommend is more suitable for me
quote · 2021-10-27 10:28
You know what I want? Macro that replaces itself with the number of arguments it received. Ability to specify that certain argument is size of array through syntax like foo(T bar[baz], size_t baz) Labels for loops and switches. labels for _Generic to expand them. Ability to define macro that expands macros inside it according to place where it was defined: #define BAR 1 #define FOO BAR #undef BAR If arguments for standard library functions are known at compilation time, these functions can be used as literals.
swap · 2022-04-12 11:37
How to start a project? How I should start solving the problem and writing the program? I always get stuck in the beginning of a project/exercises. Also, how to use gdb? Are there any other tools I should be aware of? >>29686 >>29688 >>30481 There is also C Programming: A Modern Approach >http://knking.com/books/c2/
Mitnick · 2022-04-26 00:59
>>28279 >macro that replaces itself with the number of arguments received you can do that with a normal macro up to some finite size > 1 #define GETOVERLOAD(IGNORE1, IGNORE2, IGNORE3, IGNORE4, IGNORE5, IGNORE6, IGNORE7, NAME, ...) NAME #define COUNTARGS(...) GETOVERLOAD(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1) >Ability to specify that certain argument is size of array through syntax like Your syntax if you reorder the args, but yeah the decay to pointer behavior is like kicking dead whales down the beach because you can't do sizeof. If you make the array a pointer to an array, you can specify the size without it decaying and you're able to do sizeof(*bar), where bar is foo(T (*bar)[20]) and get the correct size, but you have an unnecessary level of indirection
Lord Nikon · 2022-05-05 16:30
I'm giving "Modern C", by Jens Gustedt, a try. And I'm really hating it. The language is dumbed down, the topics are not organized logically, and the content is introduced slowly. Maybe I'm being biased, because I learned C with K&R, which is the complete opposite: it uses a technical language, the text is organized and can be referenced, and it's a very terse book. Also, Modern C has not added anything that I do not already know.
John Doe · 2022-05-05 18:28
>>31079 That is sad. I was going to read it looking for a up to date C book since it's been decades since I programmed in C(non-ansi in a msx) and wanted to try it again.
over · 2022-05-06 12:04
>>31091 Interesting. Thank you, anon.
Frank Garza · 2022-08-21 12:18
>>28031 >why is this? what's wrong with bool. Interesting Question I would love to know the answer to. Perhaps related to the fact that virtually all operators return an integer type. For instance, x < y produces a 1 or 0 as an int , not a boolean. >>28044 >Because bools are implemented in kinda retarded way where they have random-ass size. Your wrong. All variable types in C have an unknown but ordered size called 'Rank'. This was supposed to be a feature, and it has allowed programs to scale from 70s hardware to modern machines with size_t /int etc scaling according to implementation requirements. Now, this is somewhat considered annoying for portability, and so stdint.h types exist now. Suckless can't be saying prefer int to bool because sizeof(bool) is unknown , because sizeof(int) is equally unknown. Also, bool is guaranteed by standard to have lowest rank integer type. May be a bit. In practice (x86 Linux/GCC) its a byte. The only reason I can think of to prefer bool is to allow an implementation the ability to save space. In practice, I don't know of any that do.
se7en · 2022-08-21 20:26
I am the OP of the first C Programming Thread. I wish to apologize for my abrupt departure. It is true that having reached a point where I was trying to plot the data output from my investment calculator sample program had hit a roadblock, I took some time to calm down. I progressed very far I think considering that I started the entire C Programming persuit to spite a rude poster who called me a skid for posting a Posix Script. In the time since I have gotten employed, lived to a schedule, and have just been in a general realm of self-improvement. This has excluded continued practices in C Programming however. I do hope to return to learning the language, and probably will just skip trying to make a linear plot of the investment data and move on to more manipulation of the calculator itself. I thank you for all the feedback I recieved in the initial thread, and I am glad to see that the C Programming Thread I started continue all this time later. This was a good way to start off the New Year, and I do plan to return if not in the immediate future than in the near future. Thank you, Lainchan.
Shogun · 2022-08-22 13:53
>>32468 > started the entire C Programming persuit to spite a rude poster who called me a skid for posting a Posix Script. This is definitely everything wrong with taking advice from image boards. You shouldn't take any advice that isn't supported else where from an image board. >http://widgetsandshit.com/teddziuba/2010/10/taco-bell-programming.html <The more I write code and design systems, the more I understand that many times, you can achieve the desired functionality simply with clever reconfigurations of the basic Unix tool set. After all, functionality is an asset, but code is a liability. <Here's a concrete example: suppose you have millions of web pages that you want to download and save to disk for later processing. How do you do it? The cool-kids answer is to write a distributed crawler in Clojure and run it on EC2, handing out jobs with a message queue like SQS or ZeroMQ. <The Taco Bell answer? xargs and wget. <Taco Bell programming is one of the steps on the path to Unix Zen. >https://leancrew.com/all-this/2011/12/more-shell-less-egg/ <Knuth wrote his program in WEB, a literate programming system of his own devising that used Pascal as its programming language. His program used a clever, purpose-built data structure for keeping track of the words and frequency counts; and the article interleaved with it presented the program lucidly. McIlroy’s review started with an appreciation of Knuth’s presentation and the literate programming technique in general. He discussed the cleverness of the data structure and Knuth’s implementation,pointed out a bug or two, and made suggestions as to how the article could be improved. And then he calmly and clearly eviscerated the very foundation of Knuth’s program. <What people remember about his review is that McIlroy wrote a six-command shell pipeline that was a complete (and bug-free) replacement for Knuth’s 10+ pages of Pascal. Larpers on the innanets imagine that they are leet hackers because they fantasize about writing a program in C, equating it with leet. Working Programmers write what gets the job done. If you want to learn C, learn C. Its a beautiful language. Don't conflate a tool that can be the right choice for some problems, and give you a deep understanding of the OS environment you run in with the ONLY choice for all problems. Realistically, there is no difference between an investment calculator in C, Python and Shell except that python is probably easiest to maintain and most portable, and most likely to be free of bugs. As a learning exercise for yourself, any language is appropriate.
Davis · 2022-08-23 19:11
>>24853 This will fail on a blank lines, like s == "\n\0" for example. filter_line will set last_char to 0. The first for loop won't change it because s has no text chars. The second for will set last_char=1, ignoring the first character of s. Thus, s will be unchanged.
Dr. X · 2022-09-02 23:17
im too much of a fool to understand this soykaf idk how i even made it this far in K&R, ive just been barely scraping by on each exercise is there a more fool book than this that i can learn from? i need like more handholding i guess. this whole section, section 5.12, about "Complicated Declarations", it's not sinking in for me at all. its frustrating. i wish this book was more like that Stroustrup PPP book or C++ Primer or some soykaf. is there like a definitive list of books for learning C that doesn't include K&R? i want to learn C but this book is hard af. can i just skip this 5.12 "Complicated Declarations" section? i mean i feel like i barely scraped by learning about pointers to functions even after watching multiple youtube videos on the topic.
Undisclosed · 2022-09-03 09:12
>>32626 See: >>32627 tl;dr K&R was written for programmers and not for beginners. Moreover, K&R is outdated book. It doesn't teach you which stdlib functions are unsafe. Instead of K&R you should read C Programming: A Modern Approach, 2nd ed. or Primer Plus by Prata. Enable all compiler warnings (-Wall -Wextra -Wformat=2) and use Valgrind and a lint a lot.
Motoko Kusanagi · 2022-09-11 03:49
>>32704 man offsetof (Post not long enough, sigh.)
Hacker · 2022-09-23 15:39
For Windows, what's better, MSVC, ICC or MinGW? And does it even matter?
Miho Iwakura · 2022-09-25 02:58
>>32838 In my opinion, use msys2. You can use GNU/Linux utilities that are available from the msys2 repo. It has clang as well as GCC. MinGW is a bit outdated.
BloodCat · 2022-09-26 09:32
>>32838 >For Windows, what's better, MSVC, ICC or MinGW? And does it even matter? MSVC doesn't support "modern" C standards like C99. You should use either MinGW/Msys2 or Clang. Or just dual-boot Linux and Windows.
Guthrie · 2022-09-26 09:40
>>32858 >Or just dual-boot Linux and Windows. Why the fuarrrk would I "just" dual-boot Linux when the question was regarding the compilers available for windows and what about ICC? does it have any drawbacks?
over · 2022-09-26 11:37
>>32859 >Why the fuarrrk would I "just" dual-boot Linux when the question was regarding the compilers available for windows I gave you other options first. But the truth is that programming in C is harder on Windows and less convenient. That's a simple fact (I have tried it on both operating systems). >what about ICC? does it have any drawbacks? Don't bother with it. GCC and Clang are better for general use. However, ICC can optimize the code slightly better than other compilers but only if you use Intel CPU: >https://www.agner.org/optimize/blog/read.php?i=49 >Will Intel be forced to remove the "cripple AMD" function from their compiler (ICC)? >If the vendor string says "GenuineIntel" then it uses the optimal code path. >If the CPU is not from Intel then, in most cases, it will run the slowest possible version of the code, even if the CPU is fully compatible with a better version.
Dozer · 2022-09-26 21:10
>>32861 >programming in C is harder on Windows and less convenient how so? You can open Visual Studio and start writing C on it (using MSVC or ICC). Or you can also use gcc on the cmd just like you'd do on linux. I'm not sure about using gcc on visual studio, but probably possible as well. And Windows.h is a great library
aliased · 2022-09-27 17:39
>>32864 1) win32 is generally more painful than POSIX. 2) I've had some fuarrrkery when colleagues using Code Builder (god save their souls) didn't have access to UCRT/MSVCRT functions. 3) The entire Windows world is for monkeys that can only survive in the "click button obtain banana" world, where you'll never learn anything about low level hands-in-oil stuff that manually writing makefiles forces you to.
Junichi Fujiwara · 2022-09-28 02:42
>>32868 >the good ol' "worse is better" unix philosophy. I'm a smug Lisp weenie, friend. >since when is "manually writing makefiles" low level stuff? Since IDEs exist. >you can also do it manually on windows, but why would you bother with it? To learn about linking, preprocessing, compiler flag management, etc... >not everyone using windows is retarded Right. The only people I've seen in my life (academic and work) that fit your description just didn't care.
Faye Valentine · 2022-10-01 13:45
is it worth using C for opengl? not for gamedev, but I want to learn to use it for GUIs that need to be fast, since my endgoal is using it for making a cross-platform CAD program. Also, does someone know some resources for it? the only ones i see to find are for c++, but i don't wanna use c++
Jet Black · 2022-10-01 15:00
>>32898 it's trivial to port tutorial-level c++ code to c though. by far your biggest hurdle will be actually writing the damn program, not figuring out basic programming syntax in tutorials / manuals
Trinity · 2022-10-01 18:37
>>32898 Most books do use C++, but the takeaway is the state machine model of OpengGLand the functions you call to manipulate it. There's nothing in the code in most books that depends on C++ in any significant way, certainly nothing that affects the way you use OpenGL. It is actually a C library, not a C++ one.
Knuth · 2022-10-01 23:38
>>32899 >>32900 thanks anons. another question, is learnopengl.com a good resource?
Gyula Kovacs · 2022-10-11 13:44
Is there any way to do "automatic" pointer arithmetic by mapping members of a structure to a given offset of a master pointer? For example, let's say I copy file "A" from HD to a memory block "void* data_A" and file "B" to "void* data_B", they have 3 bytes, each byte represents an information and all my files have the same structure. So I create a structure: struct data { void* master; int8_t *a; int8_t *b; int8_t *c; }; And with it I map "a" with offset 0, "b" with offset 1 and "c" with offset 2. So just changing the pointer "master" to a new block of memory I can access "a", "b", and "c" abstractly without doing arithmetic with "master". I don't want to load the file straight into a structure, but keep it in a continuous block of data.
Spike Spiegel · 2022-10-11 19:04
>>33028 struct Header { int8_t a; int8_t b; int8_t c; }; void* data; Header* head = (Header*)data;
Chan Siu Ming · 2022-10-15 16:20
Are there any data structure book using C? The only interesting one I found was from before ANSI C.
aliased · 2022-12-09 15:57
>>24824 Is it worthwhile learning C with the second edition of ANSI C Programming? I don't imagine it would've changed significantly from then to now, but I want to be sure so I can know that I'm not learning stuff that'll be wrong if I want to use modern C.
null · 2022-12-09 19:00
>>33700 It's fine but it's usually "int main(void)" and not simply "main()", use "const" instead of "#DEFINE" (also you should const every variable and function return type by default as it's good practice unless you know the variable needs to be modified), and avoid using unsafe functions like scanf in production code. Scroll up your question has been answered multiple times.
queue · 2022-12-13 04:23
>>25040 Yeah, Python is fine if I want to just get something done straight away, like a automation script, or if I want to get some quick maths done in terminal, but I don't like to stay around in it for projects. Not a fan of indentation=scope, and I want to get into low level programming job.
Nobody important · 2022-12-16 07:09
>>33739 >I want to get into low level programming job Every C job I've had used Python or Perl for test scripts so it's probably not something you can just ignore entirely. >>33704 There's nothing wrong with scanf. Maybe you're thinking about gets or something.
Hagbard Celine · 2022-12-19 14:07
>>33750 scanf unsafe use scanf_s https://stackoverflow.com/questions/2430303/disadvantages-of-scanf#answer-2430978 https://code.fandom.com/wiki/Scanf_s
Jean Dupont · 2022-12-19 14:21
>>33760 >scanf unsafe use scanf_s Or just fgets
Project 2501 · 2022-12-20 05:28
>>33760 >microshit vendor lock yeah, no. >>33750 scanf is a problem, not a solution. http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
Naomi Nascimento · 2022-12-27 13:40
>>33750 who the fuarrrk needs tests lmao
Project 2501 · 2022-12-30 07:10
>>24826 >Don't write C unless you absolutely have to I'm not sure if it's what you're looking for, but it sounds like this sheep dude from the C23 committee: https://thephd.dev/
Mitnick · 2022-12-30 07:57
>>32626 To add to what >>32631 wrote, if you find that Valgrind is too slow or interferes with your code, you can replace it with sanitizers. >>32864 >>programming in C is harder on Windows and less convenient how so? The POSIX standard has many small but convenient C functions that are absent on Windows. See man strdup and man strtok_r for two examples, but there are many more. >>24883 Not that anon but I recommend i_last_char or i_last if it's an index rather than a character. >>24890 >>25040 I like writing Python+C for programs that have an algorithmic component. It's a great combination because Python lets me make a beautiful CLI that's pleasant to use with few lines of code, and do other common stuff like downloading and parsing webpages, but then I can optimize the core algorithm a lot in C. >>25179 Same. Unfortunately it looks like a lot of this isn't going to be fixed due to backwards compatibility. At least thephd.dev thinks so. >>25884 - C Programming: A Modern Approach by King is a great book for beginners. - For a simple project a Makefile should be enough to build it. For more complex stuff I recommend Meson or CMake over autotools. - C unfortunately has several dangerous functions that you should use with great care or not at all. Usually you can recognize them because they copy/manipulate stuff without taking a length parameter. Two examples would be strcat and strcpy. A good rule of thumb is to always use strncpy/strlcpy and strncat/strlcat instead. - When using the functions which take a length, read the manual and keep in mind whether the length includes the null terminator. If you don't, it's easy to make an off-by-one error and write the null terminator to something adjacent in memory. - -Wall, -Wextra and sanitizers are your friends. Use them. - You can make int constants without using the preprocessor like this: enum { MY_CONSTANT = 42 }; - The pointer star modifies the value to the left, not the type to the right. That's why C programmers write type *value instead of type* value . - Don't overuse macros. >>26003 Your overuse of macros is hurting the readability of the code. A few bytes for a constant doesn't matter. Programs should be written primarily for humans to read, and only secondarily for computers to execute. >>26315 I avoid extensions that are only provided by one compiler. I do use extensions that are in both GCC and Clang, but I do it sparingly when their utility outweighs their lack of portability. >>26855 >Are there any advantages of learning C over other languages? A great advantage of C that most newer languages don't have is its simplicity and predictability. You can hold the stdlib in your head, and you can know what the code does by looking at it. In C++, for example, a simple a + b can be doing lots of work and even memory allocations behind the scenes if the + operator has been overloaded. In C, you know that if it doesn't look like a function call, it isn't. >>27428 You'd have to be more specific and give some examples. It sounds like you could be doing unnecessary premature optimization. You can just share a struct in memory between threads. >>27520 These two projects should provide good inspiration: https://github.com/seanbaxter/circle/blob/master/reflection/README.md https://ziglang.org/ >>27979 >What do you think about C23? I like it a lot. I was afraid they would stray from the C philosophy of simplicity and introduce stuff like lambdas and exceptions. But they actually made choices I mostly agree with. I think it's a very good standard. >>28031 Nothing. You should use them because they make the code more readable. The suckless philosophy is weird. >>30734 I just do it in an "iterative" way rather than trying to have everything planned out in advance like the enterprise UML people. 1. Write a simple Makefile/CMakeLists.txt and main.c. 2. Write a basic half-functional proof-of-concept with some hardcoded input, some functions returning dummy data, etc. Add a // TODO comment for every shortcut. 3. Check if it works as expected. 4. Replace all the dummy implementations that have TODO comments with actually good ones. Create a nice CLI with argp.h, parse the input well, handle edge cases, etc. Keep checking if it works along the way. 5. Polish up the code. Refactor it to make sure it's readable and follows best practices. (Going for a coffee or a walk can help gain a fresher perspective.) 6. If it needs more speed, write highly optimized implementations of hot functions. >>33704 >use "const" instead of "#DEFINE" I would argue that you should use enum instead of #define when you can.
() · 2023-01-06 02:08
>>26085 I knew suckless was a meme the second I understood what a pile of steaming soykaf X11 is. Because these midwits insist that using it is somehow more simple than any other alternative. It's like all the rust trannies running around claiming that the whole pile of unsafe code running under their programs can be magically ignored because they used an unstable (both API and ABI-wise) supposedly safe language on top of it. Computers are soykaf, just like everything else in life - make the best you can of it but don't dare to think things are perfect or can be easily made so.
Terzibashjian · 2023-01-06 13:14
>>33880 I have never seen a Rust evanglist claim that their platform is secure, due to running on it a Rust binary, I call strawman. I don't even know Rust. Suckless is a great fine idea, even if the people associated and its fans can be insufferable. The computers are soykaf view is exactly why people tend to be excited about new ways to enforce order upon their programs, such as Rust. How is it Rust's fault if platform-ABI's are unstable, again btw?
pop · 2023-01-07 04:35
>>33880 >I knew suckless was a meme the second I understood what a pile of steaming soykaf X11 is. What's the portable alternative that is like kicking dead whales down the beach less? Suckless people aren't dumb, and of course see the suck in X11 but better this than the current Wayland situation. >>33883 >Suckless is a great fine idea, even if the people associated and its fans can be insufferable. To be honest, there should be a big divide between suckless devs and "users" aka nogrammer ricers playing around with dwm patches without even knowing C.
John Titor · 2023-01-08 08:29
>>24826 The person who tells you to not use C is not a C programmer. So much so that s/o/ykaf restricts his usage per his weaknesses with regard to C, rather than by the strengths of other languages. >>33880 Any other window server than X11 will insist that the programmer Add More Shit to their programs. For example Wayland, which insists that programs organize themselves around the window server's draw loop. This is the path of greater suck, regardless of what one thinks about the X11 architecture in general.
Knuth · 2023-01-09 16:30
We should use TUI like in notcurses
renames · 2023-01-12 10:33
>>33883 It's not platform ABIs. Rust itself refuses to have a stable ABI, much like C++ before it. This is all rooted in the "move fast, break things" approach that has taken over the whole industry.
byte · 2023-01-21 18:40
>>33826 >I was afraid they would stray from the C philosophy of simplicity and introduce stuff like lambdas and exceptions. This will never happen. C has always had the design constraint that C programs must be easy to compile on the fly on a toaster. Lambdas and templates are literally the worst 2 features to add, and even the people writing the C standard would tell you to use C++ if you really need those. The only bad thing about C23 is that noone will use it because POSIX still hasn't grown out of C99. And POSIX is so much at odds with modern OS architectures that there's little room to improve it without breaking everything.
藤原純一 · 2023-01-21 20:07
>>34048 > C has always had the design constraint that C programs must be easy to compile on the fly on a toaster. Lambdas and templates are literally the worst 2 features Yes lambdas are the worst to compile.... https://youtube.com/watch?v=H-yuZ2pejGU Oh..... Oh
Batou · 2023-01-21 20:29
>>34050 It's funny. They're always seen as two polar opposites, but when I really break it down, most of the reasons I love C are also the reasons I love Lisp. They've got a lot more in common than people think.
queue · 2023-01-22 18:59
>>34050 >a calculator can interpret small Lisp functions therefore lambdas are trivial to compile sequentially I'm starting to understand why actual programmers who accomplish stuff don't hang out on imageboards.
Hitomi · 2023-01-22 19:44
>>34068 The calculator can handle lambdas, the claim was about how features like lambda and templates make hard to compile on the fly for devices like a toaster. Lambdas just represent some form of dynamic scope switching at the abstract machine level. Which isn't that hard to implement naively. In fact it's easy to see how to get it naively inside C itself. Implement a closure data structure that has some captures and lift up the function. It's done this before at the LLVM level. Things get harder when one wants to optimize everything to the fullest, however in this case compilers work quite hard to make C fast. This should not be surprising lisp has existed for a long time on fairly constrained hardware, with inefficient compilation techniques that made the language slow on the hardware it ran on (C was also slower than hand made assembly due to similar compiler inefficiencies) In other words, lambdas are not as hard as you think. Having any variables and scoping at all is more complicated than one would think and C copes fine with having it
Bob Arctor · 2023-01-23 20:04
>>34069 By on the fly, I meant instruction by instruction, keeping as little of the previous uncompiled code as possible, not JIT.
Torvalds · 2023-01-24 18:24
>>34087 Either way the point stands, as i gave a naive translation with some minor escape analysis (don't even need that if we specify the captures ourselves), using mechanisms already found in LLVM (note in this case it also means in C). A lot of extensions on C are possible without too much effort. I'd even argue ""templates""" (hereby referred to as implicit resolution) is fully doable even on machines that require small binaries. In the implicit resolution case it's a trade off of binary size version versus speed. As specialization of each instance need not happen, an approach can be taken where an extra pointer chase is had, keeping binary sizes down and compilation fast at the cost of a pointer chase. I have not used it myself but i believe a subset of Pico lisp runs on embedded devices https://picolisp.com/wiki/?home The code is compiled (don't know if it's JITed or AOT or what, but it does not matter as the compiler has to handle efficient native code generation and that can be applied fairly well just take away a REPL [which mind you forth systems have]), i don't know if it's implicit resolution mechanism is in the embedded subset but i believe it is as its not listed as a missing feature here https://picolisp.com/wiki/?embedded
Mentat · 2023-01-24 18:54
>>34087 > I meant instruction by instruction, keeping as little of the previous uncompiled code as possible I don't know what this means.
William Holtzer · 2023-01-26 15:08
>>34068 >>34087 There's plenty of compiled languages that implement lambdas, even systems languages like C++ and Rust. Obviously they have significantly bulkier runtimes than C, but the point still stands.
Dozer · 2023-01-30 07:21
>>24830 What theme do you use for reading pdf ?
queue · 2023-01-30 12:07
>>34159 I'm pretty sure that's Solarized Light. It's well designed theme (read its home page).
Milner · 2023-01-31 19:54
>>34098 It means the compiler can output assembly lines in the same order it reads lines of the source code instead of: >read the entire source code to build the symbol table >either rewind the source code and parse it again or have the entire AST in memory >finally start outputting assembly This is the way C was always intended to compile, and lambdas simply don't allow it.
Zero Cool · 2023-02-01 07:10
>>34168 I don't see how your claim > lambdas simply don't allow it. holds at all. I mentioned in >>34097 that we can already add lambdas to c without needing a second pass, simply note in the lambda form what values you are capturing, then it is no different from compiling a top level function. I don't know how naive the compilers you are thinking of are, but if we are doing it all inline, then an alternative strategy is compile the lambda down to its blocks on the spot with the typical preamble, and then go to that. naive strategies work perfectly fine for lambdas, much like how a naive single pass compiler can work for C (it won't be the fastest, but C with single pass compilers are slower.). However for any modern compiler, they are not doing a single pass over C. To achieve fast results compilers run passes like SSA, graph coloring, block reordering, dead code elimination, etc etc etc. Thus we have seen that if we are fine with a slower single pass compiler, lambdas work! If we decide on a multi pass compiler like gcc, or clang, then lambdas can be optimized very hard and also work fine. However by your standard this is not the way C was "intended" to compile. Is there any C compiler you use that maintains the "intended" way given on high by Dennis Richie and Ken Thompson themselves
Unknown · 2023-02-01 13:32
>>34168 >>34170 Ironically, one of C's most important initial design goals was that there wasn't supposed to be any "true" way that it "should" be compiled. This was to allow C to be compiled to and run well on a wide variety of platforms, which was important if it was going to be "portable Assembly".
The Plague · 2023-02-05 09:14
>>24826 >dont use c I will now use c out of spite for any moron that tells me not to
Hacker · 2023-02-13 23:23
Hello lainchan.org I bring a very important question about C, one that I couldn't find a good answer on. It's about pointers to pointers, also known as multiple indirection, specifically about what I call "double pointers" (int **ptr). I am trying to find out equivalents on indexing these double pointers between pointer arithmetic and array notation. Basically, my actual question is: Is there an equivalent of (*array + i) in array notation? I tried (*array)[i], and array[x][y], but these seem to be doing different things and my program ends up segfaulting. Basically (*array + i) does what I actually need, it dereferences my **array into an *array, which then I can index around with pointer arithmetic. It's weird that this has no equivalent in array notation. The only resource I found was this https://dev-notes.eu/2020/04/Pointer-Arithmetic-&-Multiple-Dereferencing-in-C/ And it seems that with array notation you can only do one specific case and (*array + i) is probably impossible to do in array notation.
Dujour · 2023-02-14 16:10
>>34328 Just to make things clear. x[y] is sugar for *(x + y), and (*x)[y] is sugar for *(*x + y), ... So (*array)[i] would be equivalent to *(*array + i). Here, you're dereferencing two pointers; first, array, which gives you another pointer. Then, that pointer + i, which gives you the value at the address. If you're taking the pointer elements of array without dereferencing,e.g. item = (*array + i), then you're looking for &(*array)[i]. Anyways, find a better name for your "array", because it definitely doesn't look like one.
let · 2023-02-15 10:22
>>34174 >there wasn't supposed to be any "true" way that it "should" be compiled Bullshit. The reason why that language is full of undefined behavior is because it's intended to be implementable in extremely naive ways.
Roy Batty · 2023-02-16 03:33
>>34328 Are you sure (*array)[y] is doing something different from array[0][y]? They should be the same. To view the address of a pointer cast it to size_t and printf it Try looking at the values of pointers themselves (their addresses) rather than what they are pointing to to compare them and debug them. also i think it would be better to do something like struct Word { char* c; }; struct Sentence {Word* w; }; struct Para {Sentence* s; }; that way you can have the type system help you and it becomes more readable. and if you want to change it from null terminated lists to sized lists later its easier struct Word { char* c; size_t length; };
Chan Siu Ming · 2023-02-17 18:29
>>34328 >>34351 My initial question was idiotic, thank you >>34334 The context of my question was a struct typedef'd/named str_t *a being passed by reference (&a) to a function, func(str_t **a) It is just a pointer to a struct str_t, and I needed to go through elements i of this pointer I needed to pass this to another function func2(str_t *a) Like I said (*a + i) works in pointer arithmetic, gives me a *str_t a[0][i] would give you a str_t Array subscript goes "too far" with the dereference, so like Dojour said, I just had to use & to get the address off str_t: &a[0][i] would give me the *str_t Why use 2D array notation in this case, so like Dojour said: &(*a)[i] Then: (*a)[i] is similar to a[0][i], dereferencing to a str_t. &(*a)[i] is similar to &a[0][i], dereferencing to a *str_t. Finally, &(*a)[i] and &a[0][i] are similar to (*a + i), dereferencing to a *str_t I didn't know that I could use & in this way.
dictionary · 2023-03-10 07:13
>>34048 >This will never happen. I sure hope so. However, every time the question of what C is missing gets brought up, a lot of people mention C++ features like lambdas or namespaces, so I'm not sure. To be fair, I don't know if they're actually C programmers. I would definitely overhaul some aspects of C if I could, I even have a list of those, but I think lambdas would introduce too much complexity and violate the C philosophy that everything should be explicit.
Unspecified · 2023-03-10 07:38
>>34168 I think you're overestimating the difficulty of implementing a simple version of lambdas. The real reason to avoid them is that they're not consistent with C's philosophy of explicitness. For example, thanks to the lack of operator overloading, you know that whenever you see a +, it's just going to generate some arithmetic instructions. It's not going to jump away to another function which could allocate memory or do other stuff. Lambdas would involve a lot of implicit operations: hidden extra function arguments for captured variables, data that's being implicitly passed around when a lambda with captures is given as an argument to another function, etc.
Frank Garza · 2023-03-12 19:57
Lambdas, templates and exceptions are most definitely excessive for a language like C, i.e. one that doesn't even have nested functions. With that said, even though I know it'll probably never happen, I'd love to see first class namespaces in C. Same goes for some sort of optional macro hygene. I like C, but it's got hella namespace pollution, and it makes it difficult to write 'clean' code.
Lady 3Jane.. · 2023-03-19 18:01
I'm starting to seriously get into C, and I've developed the habit of doing everything with macros if I can because it feels cleaner than having to declare separate functions to get for example the length of an int array and the length of a float array. I feel like this is probably a terrible practice, so I want to know, is it terrible, and if so, how terrible is it?
Nobody important · 2023-03-20 10:45
>>34861 Yeah, stuff like that. I also write macros to automate things like passing the size of an array to a function. For example float __MEAN__(float array[], int array_length){ float sum = 0; for(int i = 0; i < array_length; i++){ sum += array[i]; } return sum / array_length; } #define mean(array) __MEAN__(array, sizeof(array)/sizeof(float))
Wirth · 2023-03-20 13:25
>>34868 That looks useful, I guess you could use sizeof(array[0]) instead of size(float) to make it a bit more generic. The thing with macros is mostly to think of edge cases where a different person might call it unknowingly and to make sure it still behaves as a function would. Tricks like using a do...while(0) around blocks and so on. People mostly complain if they have to debug some obscure case. Two reasons I try to avoid macros in general is to have it easier to put a breakpoint in code for debugging and to have less experienced people do maintenance easier in my code. I only recently started to worry about 2nd point, I love to use macros, typedef, function pointers, unions but some people I work with cannot read this type of C. They never bothered to learn because they can solve all their problems with for loops, if statements and brute force. I hate working with them but having code they can maintain means more free time in my weekends. Sometimes I'm asking gcc to expand my macros before giving code to them.
Bobby Newmark · 2023-03-22 12:47
>>34869 >I guess you could use sizeof(array[0]) instead of size(float) to make it a bit more generic. I actually did at first, I was just worried it would negatively affect performance. Is there actually a difference, or am I just doing things the hard way for no reason?
Cereal Killer · 2023-03-22 21:23
>>34890 sizeof is evaluated at compile time so there is no difference in perf another useful macro would be this one that gets the number of elements in an array #define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0]))
Acid Burn · 2023-03-23 11:06
I've once come across with some a way to make generic "vector" using pointers, but i don't know if this is alignment safe. typedef struct { size_t element_size; size_t n_elements; } ListHeader; void * __create_list(size_t element_size) { ListHeader *header = calloc(1, sizeof *header); header->element_size = element_size; return header + 1; } void * __resize_list(void *list, size_t n_elements) { ListHeader *header = (ListHeader*)list - 1; header = realloc(header, sizeof *header + header->element_size * n_elements); if(!header) return NULL; header->n_elements = n_elements; return header + 1; } void free_list(void *list) { ListHeader *header = (ListHeader*)list + 1; free(header); printf("List freed. :)\n"); } #define create_list(type) __create_list(sizeof(type)) #define list_push(list, ...) (list = __resize_list(list, list_size(list)+1), list[list_size(list)-1] = __VA_ARGS__) #define free_list(list) free((ListHeader*)list - 1) #define list_size(list) ((ListHeader*)list - 1)->n_elements #define list(type) type* >>34868 That's a very useful pattern indeed, i use alot when i do a Vertex Array Object creation. Becomes something like this: #define CREATE_VAO(info_list, ...) create_vao(sizeof(info_list) / sizeof(info_list[0]), info_list, (GLuint[]){ __VA_ARGS__ }) And an array of a struct that i define becomes the "skeleton" of the vao. There's also a way to make a safe variadic arguments using this as well, but becomes a little messy. #define LINK_SHADER(program_ptr, ...) link_shader(program_ptr, sizeof((GLuint[]) { __VA_ARGS__ }) / sizeof(GLuint), (GLuint[]) { __VA_ARGS__ }) static void link_shader(ShaderProgram *program_ptr, GLuint n_shaders, const GLuint *shaders);
Mitnick · 2023-03-23 20:30
I pretty much always use blocks for control-flow, even when it isn't necessary. For example, instead of if(1 == 1) return 0; else return 1; I typically write if(1 == 1){ return 0; } else{ return 1; } Does doing it this way impact performance in any way, or am I just paranoid?
Emmanuel · 2023-03-23 21:49
>>34898 The compiler shouldn't act any differently, but you never know how retarded GCC or Clang/LLVM can be. Using Godbolt, I can't see any difference in the outputs. I compiled a small program locally with optimizations turned off in GCC (-O0) and both binaries are exactly the same. Doesn't look like you need to worry.
vector · 2023-03-24 04:51
>>34898 they are the same, it would be a compiler bug if the codegen was different additionally you can add scopes {} without an if statement by themselves if you want to separate things into blocks without pulling them out into another function
synchronized · 2023-03-24 10:01
>>34899 >>34901 Good to know. I like to have my code as optimized as reasonably possible. Like, I'm not going to bend over backwards and do retarded nonsense to save half a millisecond, but if there's a way to make things faster while still writing code that I can read and debug later, I'm going to take it.
⍕ · 2023-08-23 04:55
>>34710 >hella namespace pollution, and it makes it difficult to write 'clean' code. You can just use prefixes everywhere. For example, randomness functions all start with rnd_ and are implemented in rnd.c, matrix functions start with matrix_ and are implemented in matrix.c, colorspace functions all start with color_ and are implemented in color.c, etc. For types, I usually use PascalCase but also prefix everything, e.g. RndState, ColorSpace, Matrix. >>34868 I would argue you're overusing macros for the sake of saving a few keystrokes. I used to do that to in my first years of writing C, but then I realized that most of the time, brutally simple imperative code is best. So I'd write your function as #include <stddef.h> float mean_f(const float *nums, size_t n_nums) { float sum = 0; for (size_t i = 0; i < n_nums; i++) { sum += nums[i]; } return sum / n_nums; } and then just pass a pointer/length pair, which is a very common idiom in C. Reserve macros for the cases where they're actually necessary or shorten the code a lot. You'll thank yourself later when you have to maintain and debug your programs. Also, names beginning with two underscores are reserved for the implementation. Don't name your functions like this. >>34890 It's not. Most of these micro-optimizations are snake oil that just makes your program harder to read while getting optimized to the same assembly as the readable version anyway. True performance usually comes from larger-scale decisions: the right algorithms, the right memory layout, and not using excessive layers of indirection. You should worry about these and leave the small tricks like replacing i*8 with i<<3 to the optimizer, unless you've tested the code on https://godbolt.org/ and saw your tricks generate much better assembly (set the language to C and compiler options to -O2). See also <https://nullprogram.com/blog/2019/12/09/> >>34898 It should compile to the same code. I always use braces too and consider it a good practice because it helps prevent occasional errors like <https://dwheeler.com/essays/apple-goto-fail.html>. You're thinking way too much about tiny local optimizations. Modern optimizers are smart and almost always handle the small stuff for you. In the rare cases they don't, it's usually not that important anyway. Don't worry about it, and if you have to, always check with Godbolt or a similar tool, using the newest version of clang or GCC and -O2 or -O3. But in general, I recommend you think about it less. This is a much better process for writing C fast programs: 1. Decide on the data structures and algorithms that you'll use. 2. Think about which functions will be responsible for memory allocation and deallocation and how they'll do it. You probably don't want to allocate in a hot loop. You also probably want to allocate whole arrays when possible instead of mallocing tiny pieces of data a huge number of times. 3. Write the program in a way that's as simple, readable, and well-organized as possible. Don't worry about optimization at all at this stage. 4. Check if it's fast. It probably will be because the optimizer is good. 5. If it isn't, use a profiler like Linux's perf or Intel VTune. This should tell you what the potential problems in the program are. 6. Optimize the hot-spots indicated by the profiler. Often this will involve changing memory access patterns or adding a restrict qualifier. 7. Use a microbenchmarking tool while optimizing to make sure that your changes are actually helping and you're not just engaging in magical thinking. Hope this helps.
JARGON · 2023-10-28 01:28
>>33065 This book is a little bit old, but I learned a lot from it. It's a good book if you already know a bit about C, but are looking to learn more about more advanced topics.
synchronized · 2023-12-25 12:16
Why should I use this int a = 0X64; instead of this? int a = 100;
Torvalds · 2023-12-26 16:14
>>38015 You can ask ChatGPT for countless examples where you may see it, but a non-embedded systems example is 0x00FF00 shows it's clearly green from a glance in 32-bit RGB representation.
Dujour · 2023-12-29 17:20
>>38015 Are you doing bit-level stuff? No? Then you shouldn't. Also, don't capitalize the x. It makes it significantly less readable.
Faye Valentine · 2024-01-03 21:21
>>24853 Holy soykaf, can't believe this thread is still up. It's been 2 years and 3 months since I made this post. I made this post before I began my studies as a software engineer, and now I'm a few months away from finishing. Lot's of memories rushing back in now. There are so many laughable mistakes in this code snippet. I can still remember sitting at my desk with my thinkpad trying to figure it out. I wanted to finish K&R before I began my studies, but I didn't end up getting very close. Still, that book was invaluable to me, having completed the exercises or not. Here's my crack at writing the exercise now: #include <stdio.h> #include <stdlib.h> // Returns pointer to last encountered printable char in string. char *get_last_char(char *str) { char *index = str; char *ptr_last = NULL; for (; *index != '\0'; index++) if (*index >= ' ' && *index <= '~') ptr_last = index; return (ptr_last); } char* trim(char *str, size_t len) { char *ptr_last = get_last_char(str); if (!ptr_last) return (NULL); char *trimmed_line = calloc(sizeof(char), (ptr_last - str) + 1); if (!trimmed_line) return (NULL); for (int i = 0; &str[i] <= ptr_last; i++) trimmed_line[i] = str[i]; return (trimmed_line); } int main () { char *buf = NULL; size_t bufsize = 0; if (getline(&buf, &bufsize, stdin) == -1) { if (buf != NULL) free(buf); return (1); } char *trimmed_line = trim(buf, bufsize); if (!trimmed_line) return (1); printf("%s", trimmed_line); return (0); } I took the liberty of making it so that it trims all non-printable characters, not just tabs and blanks. There may be a few potential oversights but I can't be arsed to extensively test it. Should work well enough.
Unsigned · 2024-01-05 15:07
>>38015 one is decimal and the other is hexadecimal... use decimal if you are working with decimal.... use hexadecimal if you are working with hexadecimal....
Arisu Mizuki · 2024-01-06 14:43
Can I make a game using C and without third-party libraries? Like Nethhack
JARGON · 2024-01-06 19:27
>>38066 Yes, you would just use your systems SDK libraries, like Win32 or X11 or Cocoa
Frank Garza · 2024-01-06 19:44
>>38070 Can you tell me more? How can I do it?
Wintermute · 2024-01-07 07:21
>>38066 Sure you can. If you want to make a pure text game, you don't need anything besides the standard library. For something like nethack you can use ncurses, which is relatively simple and comes with just about any unix system. You could also sidestep ncurses by using termcap but that's more work for you as they are low level operations. If you want graphics support you can use x11 primitives. I'm not familiar with them but I think they are at quite a low level meaning you have to implement most things yourself. >>38072 find a tutorial and documentation on the library of your choosing. A game usually consists of a loop that repeats for each turn, it reads input, or listens to events, updates the state, and draws the screen.
Lainon · 2024-01-08 02:52
>>38072 Never programmed with those SDKs but if you want to learn Win32 API, most people will recommend you to just learn from the https://handmadehero.org/ For X11 there is just no good resources. Just collect a little bit from here and a little bit from there.
sizeof · 2024-01-08 03:51
Hello sars please rate my codes. I work very hard.
sizeof · 2024-01-08 22:22
>>38066 handmade hero is about doing this you could look at ncurses if you're specifically interested in TUIs
over · 2024-01-09 12:27
>>38077 >>38085 >>38095 Wow, thank you so much. So, if I wanna do something like first pic, I should use the ncurses library or termcap. Instead, if I wanna UI/graphics, I should use system's SDK, e. g. if I wanna create Windows programs (like the second and third pic) I should use the Win32 API, and, of course, using just C/C++ Also https://handmadehero.org/, another good source?
Junichi Fujiwara · 2024-01-09 17:01
>>38103 Just be aware that GDI for Win32 does not support V-sync and its support for scaling bitmaps is poor because scaling is not GPU hardware accelerated and from what I've read it apparently does near-neighbor scaling for smaller than 150x150 px bitmaps but bilinear interpolation for larger and there's no way to specify which one to use. If you don't need either of these things for your 2D game, or fancy shader effects (e.g. night time effect), then it should be fine otherwise.
Hopper · 2024-01-15 17:20
>>38104 I found raylib. It's very simple and useful, I created a Pong game!
The Phantom Phreak · 2024-01-19 18:44
Would it be useful to read The C Programming Language if I am learning C++? Also, a good book for learn C++?
Eldon Tyrell · 2024-01-20 13:22
>>38154 C++ isn't C. It's a lot like C in a lot of ways, and it's relatively easy to port C code to C++, but from a philosophical standpoint they're very different. With that said, learning any language will make you better at all the others, because it gives you a more complete view of what programming is from a universal conceptual standpoint (as opposed to a contextual technical one).
The Phantom Phreak · 2024-01-31 06:50
C will never die because working with C++ ABI is like kicking dead whales down the beach. C is like the latin of programming languages.
Crazy Jake · 2024-02-05 12:22
Is this a C/C++ thread? I think it could be. I have a general question about files. I have a couple of .cpp files, and I want to use them in a main function (or put them in main.cpp). What is the most efficient way to do it? With headers or something? Basically, I'm dividing a big program in little files and put them together.
Wirth · 2024-02-10 15:42
I spent 10 fuarrrking years at my local Electrical Engineering Faculty grinding for a Computer Engineering Degree (I am still to defend a thesis to get the actual degree). I suck at Electrical/Electronical Engineering topics. I wanted to focus on Computer Science topics. I also want a job as a Software Engineer. I always hated webdev, but apparently it is the most accessible area in the awful current state of the industry. I've been studying/practicing Python, SQL, Flask/Django and some other soykaf. I wrote some (quite small) projects. I've applied to at least 200 junior positions since january 2023. I've had maybe five interviews and only one coding interview so far (failed hard). Right now I am experimenting some nostalgic feelings. We used C in the Faculty, for which I am grateful. But I was never too god with it. Always felt my brain was too smooth for using C. In the last few months I've toyed around with C++, which I know is also an incredibly complex language but it still feels miles easier than writing pure C. I wish I could get a job as a C++ programmer but I have to admit I still have more practice with Python. Last week it has been very present in my mind that I need way more practice with Data Strucutres and Algorithms. I should be able to do Neetcode's problems. So I tried to do them with Python but, I don't know, it feels wrong. Tried to write a singly linked list using C++ and I just said "fuarrrk it, I'll do it in C", I grabbed my physical copy of K&R that was collecting dust since the Faculty, and here I am (procrastinating a little while writing this). Wish me luck boys.... Or tell me that I'm wrong and I need to stick to Python. After 10 years in the faculty and one year of begging for a Jr position that won't come.... I'm starting to not care about anything.
Tank · 2024-02-10 16:42
I'm currently learning C and I'm deeply unsettled by how a[10], a[], and *a are kinda the same thing. I also dislike the fact that by default you need a lot of flags in order to detect basic soykaf like buffer overflows, I wish this was default.
Jean Dupont · 2024-02-10 17:53
>>38321 They're only the same when used to declare function parameters in pre-C99. In C99, you can add the static keyword inside the brackets (e.g. a[static 10]), and it will specify that if the pointer passed to that parameter doesn't point to an array of size at least what you specify, the behavior is undefined. Compilers may use this as an assumption to optimize the function body. Also in C99 and later, you can declare a function parameter as a VLA and potentially make it execute code before the function body (e.g. a[printf("λαιν\n")]). This is completely useless other than to brag about how you can write entire programs with empty function bodies. When declaring variables, they were never the same. What kind of flags are you talking about for buffer overflows?
Yuki Nagato · 2024-02-22 09:48
Why can I return an array like this typedef struct { float elements[3]; } vec3; vec3 make(float n){ return (vec3){{n, n, n}}; } but not like this typedef float vec3[3]; vec3 make(float n){ return (vec3){n, n, n}; } Am I not essentially doing the same thing? What makes the struct special?
Leto Atreides I · 2024-02-22 12:03
>>38408 Because a C array is represented as a pointer (sortof). To make an analogy: int f(struct vec3) { ... }; int g(int[3]) { ... } In f the struct is passed by value, in g the array is passed as a pointer. A bit of assembly might make it clearer (using ints to avoid SSE and gcc -O3): struct vec3 { int e[3]; }; int f(struct vec3 v) { return v.e[0] * v.e[1] * v.e[2]; } int g(int v[3]) { return v[0] * v[1] * v[2]; } 0000000000000000 <f>: 0:48 89 f8 mov rax,rdi 3:48 c1 e8 20 shr rax,0x20 7:0f af c7 imul eax,edi a:0f af c6 imul eax,esi d:c3 ret e:66 90 xchg ax,ax Registers are 64 bit and ints 32 bit, so e[0] is in the lower half of RDI, e[1] in the upper half of RDI and e[2] is ESI. (hence the shift right by 32 bits, which I admit puzzled me at first) 0000000000000010 <g>: 10:8b 07 mov eax,DWORD PTR [rdi] 12:0f af 47 04 imul eax,DWORD PTR [rdi+0x4] 16:0f af 47 08 imul eax,DWORD PTR [rdi+0x8] 1a:c3 ret Here it loads 3 times from RDI, which is a pointer to the array.
Terzibashjian · 2024-02-22 19:15
>>38408 Old versions of C could only return struct pointers from functions, not structs themselves. Just like how arrays can only be returned as a pointer. They added the ability to return structs later but didn't extend this capability to arrays.
Roy Batty · 2024-02-23 21:26
>>38410 Very in depth. Thanks. >>38415 Do you think there is a chance that C will ever support returning constant length arrays too?
Judge Fang · 2024-02-24 08:32
>>38419 In general, C tends to introduce new features into the standard only after they've already existed in the form of widely implemented extensions. I don't know how many C compilers allow you to return arrays from a function, since I avoid extentions as much as I can, but if enough of them do it, the answer might very-well be yes.
sizeof · 2024-03-09 15:52
I'm someone who occasionally has to bind C language routines, and it's frustrating when I must dig into the type definitions and text replacement macro expansions. Is there some tool I can use which gives me the primitive definition of a type, or the lowest expansion of a macro? Someone in one of the sh threads here shared a little program that handles macros, but it sometimes gives another macro as its answer. Is there a good solution to this problem, or am I stuck wading through header files for each system I plan to target? >>38222 No, ALGOL is the Latin of programming languages. The C language is like a Romance language, derived from ALGOL while dropping many of its complex features.
Wintermute · 2024-03-09 18:29
>>38505 Most of C's ALGOL influence was via BCPL, but IIRC its type system was directly based off of ALGOL 68's. It's funny it shook out that way, because otherwise ALGOL 68 was a giant nothingburger.
Church · 2024-03-09 18:53
>>38506 The chain is ALGOL, CPL, BCPL, B, and then C. An example of another chain is ALGOL, Pascal, and then Ada.
John Titor · 2024-03-09 18:56
>>38505 g++ has the option -E which outputs only the preproccessor output
quote · 2024-03-09 19:20
>>38509 Yes, the aforementioned little program uses that option, but it doesn't help with type definitions, and occasionally requires multiple invocations for some macros.
Mitnick · 2024-03-09 20:07
>>38510 Oh, here's where that little program was hiding: >>37292
fsociety · 2024-03-10 18:35
>>38510 If typedefs are the problem then i think manually parsing the code is needed to substitute them. Treat the typedef as if it were a c macro and substitute it with the macro expansion.
Naomi Nascimento · 2024-03-10 21:28
>>38522 I know there was a classical UNIX tool that explained function pointers given to it, as an example. So, no tool has ever been made to automate this? What a drag.
Davis · 2024-03-11 02:43
>>38523 It is ridiculous that compilers don't have features like this built in. >>38522 It wouldn't be that difficult to write a C program to replace the typedefs after g++ replaces the macros. Iterate char by char through all the files When typedef appears find the ';' following it, the identifier before the ';' is the name of the typedef and the rest of the text is the type. Again iterate char by char through all the files, adding each char to a different output buffer. This time checking all identifiers (consecutive chars containing only A-z, 0-9, _) if they are the same as any of the typedefs. If they are the same, instead of outputting the typedef identifier to the buffer output the typedef type text.
Miho Iwakura · 2024-03-11 13:28
>>38527 I've found a decent solution for the typedef problem: I can use the little sh program, and pipe its output into grep, searching for lines containing typedef and then a second grep searching for lines containing the type's name. There are obvious problems with this approach, one of the most obvious being the possibility of a typedef split across lines, but it should suffice regardless of its pathetic nature.
H.R. Giger · 2024-04-08 15:28
>>38419 Array decay would limit the usefulness of returning arrays, if it were added to the language. You can use output parameters instead. I like to pass the length as a separate argument along with the pointer and then use an assertion inside the function to make sure the array is the correct length.
aliased · 2024-04-09 14:00
How const char* works and what's the difference with char[] msg = "Hello\n"; ? When I remove const I get an error: Error (active)E0144a value of type "const char *" cannot be used to initialize an entity of type "char *" So, is "text" a variable type???
⍕ · 2024-04-09 14:11
>>38771 a const T is a value T which cannot be modified. const T* is a pointer to values of type const T. Every static string is of type const char*, because the string has a definite value that can't change at runtime.
aliased · 2024-04-09 17:10
>>38771 char msg[] = "Hello\n"; creates an array of 7 char and fills it with your string. Assuming you write this in the body of a function, this makes it an object with automatic storage duration (or local variable). The resulting array is created at runtime every time the function is called, and it's mutable. The expression sizeof msg will give you the number of bytes in the array but only if you use it in the same function the array is declared in (see "array decay" for more info on that). const char *msg = "Hello\n"; first creates a constant array of char with static storage duration (as if by static const char buff_[] = "Hello\n"; and then initializes msg as a pointer that points to it. The buffer is created only once (at compile time), and on CPUs that support it, it will make it so that trying to modify it triggers a segfault. That's why the compiler warns you about making the pointer read-write. The expression sizeof msg will give you the number of bytes in any pointer (typically 8 on 64-bit systems). So these two syntaxes for declaring strings do completely different things.
limited · 2024-04-16 23:08
I'm trying to come up with the equivalent of MSVC's #pragma section("sectionname", read) for gcc/clang. My intent is having a global read only struct. Any ideas on how can I achieve this?
Void · 2024-04-16 23:36
>>38860 You could do this manually using mmap to create a read-only memory page at a fixed address. Or creating a elf object file that contains read-only data, linking it to the executable & providing a const extern declaration so that c can access it.
dictionary · 2024-04-18 00:22
>>38860 __attribute__ section https://stackoverflow.com/questions/17807231/pragma-directives-for-gcc https://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Linker_005fSection.html
the Mailman · 2024-04-20 12:16
>>34868 float ohno(float *floats) { return mean(floats); } is going to compile, and may even run on some implementations. This becomes a particularly terrible footgun when combined with implicit array-to-pointer decay in function arguments. Please use a more robust array size implementation. Also, please use proper macro hygiene (i.e. wrap 'array' in the macro in parens like so: '(array)').
Netrunner · 2024-04-21 07:22
>>34868 You'll probably be better of making use of proper "slices" to avoid footguns like mentioned above. e.g. struct slice_floats { float *ptr; size_t len; }; You can then also provide convenience methods like push, pop, checked indexing etc. Macros also don't do any syntax or typechecking at all, they just copy-paste the arguments you give them. This can lead to awful errors. Or worse, no errors but unexpected behavior, e.g.: #define ADD(x, y) x + y int add_then_mul(x, y, z) { return ADD(x, y) * z; } For the same reason: please don't use lowercase letters for macros.
Lady 3Jane.. · 2024-04-29 11:05
I am trying to read and save .txt files in C++. But I am honestly very confused. I know there are two types of paths: absoulte and relative. I was trying to use the relative ones, which must be in the same location as the executable, but for some weird reason the terminal gives me the following message: WARNING: FILEIO: [/npc/sound/dialg.ogg] Failed to open file. However, when I do the absoulte path, it works without any problems. This affects the portability of my software, what solution can you give me, is there any way to find a "start path" (hard disk) and concatenate it with the path I want?
array · 2024-04-29 11:23
>>38980 Relative paths are relative to the current working directory, i.e. the one from where the user called the program. There is no portable way to do what you want. See https://stackoverflow.com/questions/933850/how-do-i-find-the-location-of-the-executable-in-c If you want it to be really portable, you can embed the ressource files in the executable. You can also use standard locations and an install script to move everything to the right place.
Trinity · 2024-05-04 03:53
>>38045 functions are compatible but the unused arg in trim is left out. untested, probably off by one errors everywhere. greybeard reporting, sorry if my formatting is off #include <stdio.h> #include <stdlib.h> char *get_last_char(char *str){ if(*str != '\0') while(str[1] != '\0' && str[1] >= ' ' && str[1] <= '~') ++str; return str; } char *trim(char *str){ size_t i; char *l; char *r; if(*(l = get_last_char(str) == '\0' || r = calloc(sizeof char, l - str + 1)) == NULL) return NULL; for(i = 0; str != l; ++i) r[i] = *str++; r[++i] == '\0'; return r; } int main(){ char buf[100 /* max line len */]; char *t; fgets(buf, (sizeof buf)/(sizeof *buf), stdin); if((t = trim(buf)) == NULL) return 1; fputs(t, stdout); return 0; }
Wirth · 2024-05-08 22:05
How can I get the best out of C/C++? In terms of performance, optimization, etc. I am really interested in having the best possible performance using C/C++, what tools can I use to know the performance of my programs? tips to achieve this end?
Marly Krushkhova · 2024-05-08 23:05
>>39069 Know your architecture well. On a modern processor, the bottleneck is often the memory, so: - keep data in cpu registers as much as possible (don't unroll too much) - help your cache (access memory in sequential order, don't use the same data accross cores) And use what your architecture provides you - multiple cores? Create threads (openMP is the easy way, raw pthreads might be necessary sometimes) - simd instructions? Use the intrinsics (your compiler won't do it for you) Generally avoid reinventing the wheel though. There are a lot of very good libraries that have been optimised for many architectures (boost, opencv, , so use them if you can. tldr: know your architecture
Acid Burn · 2024-05-08 23:12
PS >tools you can use profilers to find your bottlenecks, but they can be a bit funky to use on optimized code. Mostly they will only be useful for large, non-inlined functions.
Pris · 2024-05-09 03:32
>>39069 Give the computer less work to do. No code is faster than some code. Preprocess data into a more convenient form. Only store necessary data to fit more in cache, and keep data used together nearby eachother for cache locality. Write your own allocators. Linear Allocator / Bump Allocator / Arena Allocator. Memory & Object Pools. Avoid complex memory allocation and deallocation (mmap malloc free) during loops and code called every frame, instead allocate memory upfront. Avoid null terminated strings for used for anything other than linear iteration. Use SIMD and arrange data so it can use SIMD. Cache results of more expensive tasks like expensive computations & syscalls where possible, and recompute results of very simple tasks to save memory. Reserve plenty of virtual memory at the end of important dynamic arrays so they can increase in size without requiring reallocation. (Requires writing your own allocators.)
Nameless · 2024-05-09 11:16
>>39069 Premature Optimization is the Root of All Evil. Focus on your high-level logic, your algorithms and data structures, first and foremost, and figure out the small stuff once you've established a solid base. This is for two reasons. The first, and most obvious, is that this is where a good 99% of your performance gains will come from. The world's most efficient bubblesort will still be an order of magnitude slower than a mediocre quicksort. If you start microoptimizing the little things before you've worked out the big picture, you're going to end up with a lot of work that needs to be thrown out because it turned out there was a faster way to do things that you didn't think of. The second, less obvious reason, is that, as a rule, you simply don't know what kinds of fine-grained optimizations will actually speed up your software until you have something you can test and profile. I personally have written code that has spead up significantly, in one particularly nasty case by a good 50%, by fixing problems that I didn't know existed until I had a working prototype. If you're aiming for portability in addition to performance, you should keep the low-level platform-specific and high-level platform agnostic code as separate as possible. You should also write the latter in a way that gives the compiler more room to optimize things for you, because it's written for multiple platforms with potentially very different performance characteristics. On a more subjective level, I'm of the opinion that you should optimize for the weakest hardware that your software will realistically run on first and foremost, an opinion, IIRC, shared by John Carmack. If your program is fast on a slow machine it's probably going to be fast on a fast machine too.
The Fin · 2024-05-09 17:04
>>39076 Anyone paranoid about messing up while trying to be efficient and optimize shouldn't be using C in the first place.
Sabo Engle · 2024-05-09 17:26
>>39077 >best way is to carefully choose your data structures and algorithms To an extent yes but it is even more important to have proper abstractions around them so that when you find out you chose something wrong it can be changed without rewriting half the system.
John Doe · 2024-05-09 18:07
>>39083 It's not about fear of messing up, it's about not wasting time on work that's probably going to get thrown out later. Getting performant software tends to be a lot of trial and error, and you really don't know what's going to be a pain point until you start profiling. It's better to start with the low-hanging fruit big-picture things before getting into the nitty-gritty.
array · 2024-05-09 20:06
>>39076 Do you really think attempting to optimize is the biggest cause of problems in computers and software?
Unspecified · 2024-05-10 09:29
>>39086 No. You people are very presumptuous. I think attempting to optimize before you even know what needs to be optimized and how is moronic. Also, avoiding premature optimization != avoiding early optimizations period. I meant the phrase in the sense Donald Knuth did when he originally said it.
The Fin · 2024-05-10 22:51
>>39090 Then don't parrot "Premature Optimization is the Root of All Evil", that's literally the implication of that statement. Such an absolutist statement cannot be rescinded afterwards with a half-hearted caveat. Saying one thing and intending another is a failure at communication. People are told that if they fail while attempting to optimize, "premature optimization", they are bringing the "the root of all evil" upon themselves. Why would they risk that? Especially if they don't have any experience so they lack the skills.
Netrunner · 2024-05-11 05:22
>>39069 Generally, data structures are a lot more important than the code itself nowadays. Not only to keep your codebase organized but because a poor datastructure will lead to hundreds of wasted cycles waiting on memory reads (and writes). It is also harder to adjust data structures afterwards than it is to adjust code (even with proper abstractions). A common mistake I see is thinking that less instructions = better, but you also need to account for IPC. Code that executes more instructions might end up faster simply because it can reach (much) higher IPC. >>39070 >don't use the same data accross cores More specifically: avoid writing to the same buffer from multiple cores since that causes ping-ponging cache lines. Only reading from the same buffer from multiple cores is fine. >simd instructions? Use the intrinsics (your compiler won't do it for you) Modern compilers (or at least Clang, which has extremely aggressive autovectorization) do make pretty good use of SIMD instructions, though you have to make sure the compiler can guarantee certain properties easily, such as where exactly an array ends so it knows it can safe load N elements at once. For example: https://godbolt.org/z/rP6a9hW3P tolower_null doesn't use any SIMD instructions whether using GCC or Clang, but tolower_len on Clang leads to heavy unrolling and use of SIMD instructions (too much even arguably). >>39072 >Reserve plenty of virtual memory at the end of important dynamic arrays so they can increase in size without requiring reallocation. (Requires writing your own allocators.) Any decent libc allocator already does this for you. When it comes to allocation the main important thing is to reuse buffers where practical, especially in/near hot loops. Writing your own allocator is overkill when simply reusing std::vector or whatever else already nets you huge benefits.
Jet Black · 2024-05-13 17:12
>>39092 >nowadays >neurosuggesting there was time where they were not
St. IGNUcius · 2024-05-25 17:32
The next version of POSIX is complete and weeks away from publication. https://www.opengroup.org/austin/docs/austin_1409.txt >A new revision has now been approved by The Open Group on March 21 2024, and by the IEEE on May 21 2024. We expect this new revision to be published in mid June 2024. The only thing I saw leak about this next version is that it will be based on C17. Most importantly, this means the semantics of POSIX functions in multi-threaded programs will be defined more precisely. Maybe C is about to look much younger.
Nell · 2024-05-25 19:01
>>39191 >Open Group >Drafts aren't open What kind of idiot thought that was a good idea? Just another reason to ignore POSIX.
list · 2024-05-25 23:34
>>39191 You think pthreads will be based on c11 threads? I think its unlikely
H.R. Giger · 2024-05-26 07:36
>>39193 The final thing will likely be open as POSIX 2018 is. >>39194 It doesn't have to. It could be the other way around, or it could be neither like I think it works on Linux.
Backus · 2024-05-31 22:42
I'm trying to create a game engine with C and the raylib library. Most programs have buttons or graphical icon for the user, like a button for load a resource, a textbox, check box, among others. I'm using the raygui library, and it's pretty good, but some things don't work correctly or don't work as I would like. I'm really interested in creating a window with options. For example, I click on the “Object prop.” button and I get a window showing me the variables of the object. So, I think is better use the system's GUI. My question is: How to do it? How can I combine the raylib library with a Windows GUI? Is it efficient to do it with raylib? (performance, for example). I really would like to do someting similir to the Mario Bros pic. >TL;DR How can I use the Windows GUI with raylib.h? >On the other hand: How can I use Windows GUI with C? I know there are some programs that allow you to drag and drop elements and put some code in them (like Qt), but I don't want that. I just want to use my text editor and a compiler, nothing else. I'm interested on the two last pics.
dup · 2024-06-01 14:43
>>39255 >How can I combine the raylib library with a Windows GUI? There is no easy way to do that. Raylib is not designed to work together with Win32 API (Windows.h). https://github.com/raysan5/raylib/issues/1217 https://github.com/raysan5/raylib/wiki/Use-multiple-windows I would forget about multiple windows. Unless you're willing to learn Win32 API (this may take a week) and Direct3D 9 (this may take weeks if not months) and to drop Raylib altogther.
Undisclosed · 2024-06-01 15:11
>>39261 Thank you for the info.! I wrote this and works as I want: #include "raylib.h" #include <thread> #include <string> #define ShowCursor DontUseShowCursor #define CloseWindow DontUseCloseWindow #include <Windows.h> #undef ShowCursor #undef CloseWindow LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OpenNewWindow(char* text); bool showNewWindow = false; HWND hWndNewWindow; HWND hTextBox; HWND hButton; std::thread windowThread; const int TEXT_BUFFER_SIZE = 256; char text[TEXT_BUFFER_SIZE] = "Text"; int main(void) { InitWindow(800, 600, "Raylib window"); SetTargetFPS(60); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); if (IsKeyPressed(KEY_A)) { if (!showNewWindow) { showNewWindow = true; if (windowThread.joinable()) { windowThread.join(); } windowThread = std::thread(OpenNewWindow, text); } } if (IsKeyPressed(KEY_P)) { printf("%s\n", text); } DrawFPS(0, 0); EndDrawing(); } CloseWindow(); if (windowThread.joinable()) { windowThread.join(); } return 0; } void OpenNewWindow(char* text) { WNDCLASS wc = { 0 }; wc.lpfnWndProc = WindowProc; wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = L"NewWindow"; RegisterClass(&wc); hWndNewWindow = CreateWindowEx( 0, wc.lpszClassName, L"Data", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, GetModuleHandle(NULL), text ); hTextBox = CreateWindow( L"EDIT", // Predefined class; Unicode assumed L"", // Default text. WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 10, 10, 260, 25, hWndNewWindow, (HMENU)1, (HINSTANCE)GetWindowLongPtr(hWndNewWindow, GWLP_HINSTANCE), NULL ); hButton = CreateWindow( L"BUTTON", // Predefined class; Unicode assumed L"Accept", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 50, 50, 100, 30, hWndNewWindow, (HMENU)2, (HINSTANCE)GetWindowLongPtr(hWndNewWindow, GWLP_HINSTANCE), NULL ); // Set initial text SetWindowTextA(hTextBox, text); ShowWindow(hWndNewWindow, SW_SHOW); MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } showNewWindow = false; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static char* textBuffer = nullptr; switch (uMsg) { case WM_CREATE: { LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); textBuffer = static_cast<char*>(pCreateStruct->lpCreateParams); break; } case WM_DESTROY: { PostQuitMessage(0); hWndNewWindow = NULL; break; } case WM_COMMAND: { if (LOWORD(wParam) == 2) { if (textBuffer) { GetWindowTextA(hTextBox, textBuffer, TEXT_BUFFER_SIZE); } DestroyWindow(hwnd); } break; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } Although I have a few small doubts about the efficiency of this
John Titor · 2024-06-01 22:47
>>39262 You can replace C++ STL <thread> stuff with native Win32 API threads (available in Windows.h). It should compile faster. You can ask ChatGPT to try replacing it for you by pasting your code. Also you may as well add #define WIN32_LEAN_AND_MEAN prior to #including <Windows.h> to further speed up compilation.
cond · 2024-06-02 00:36
>>39269 Wow, interesting. >You can replace C++ STL <thread> stuff with native Win32 API threads (available in Windows.h). It should compile faster >Also you may as well add #define WIN32_LEAN_AND_MEAN prior to #including <Windows.h> to further speed up compilation. Could you elaborate? Please :) I'm learning Windows API.
over · 2024-06-02 01:57
>>39262 If you just want simple forms it might be easier for you to use libui instead of raw win32.
dup · 2024-06-04 08:39
Is there a portable way to perform range checks in C? I'm writing a program that works with a very wide range of numbers, and I want to make sure nothing screwy happens without me noticing.
Cutter · 2024-06-05 10:37
How should I save huge data with the FILE in C? I have a structure with 20 variables that I would like to save, what is the most efficient way to do it? I mean, is there a problem that the save function receives a lot of data?
Emmanuel · 2024-06-05 11:53
>>39295 Does if (a <= MAX && a >= MIN) { do something } else { complain } not suit your purpose? >>39304 fwrite shouldn't have any problem handling any sort of data smaller than SIZE_MAX Be careful of the portability when writing structs to files, endianness and alignments can vary accross platform. Usually, one would serialize the structs into an array of uint8_t before writing them to a file.
Hagbard Celine · 2024-06-11 21:01
Are there any guides on writing portable C? I've been trying to gain a deeper understanding of the language, and in doing so, I've come to realize just how easy it is to accidentally write something that only works on one compiler, operating system, and/or architecture. I value being able to get my code running in as many environments as practically possible, so obviously that's a very bad thing.
aliased · 2024-06-12 06:11
>>39329 Why would you want that? The only compiler and OS worth a damn are GCC and Linux and Windows.
renames · 2025-08-02 19:33
>>39329 Isn't this the whole rhyme and reason for POSIX?
Yet Another Lainon · 2025-08-02 21:16
>>24824 Don't want to derail the thread too much. but is there something like C, in terms of how small and contained/portable the language is, but is purely functional or purely OO? like, mini-haskell, or mini-smalltalk. something like that. something elegant, pure and small.
Joey · 2025-08-04 21:14
>>42713 This may or may not work for you, but SML is like the scheme of ML languages >formally defined >small and elegant It is also: >dead There are a couple implementations out there, but you won't find much by way of libraries.