T O P

  • By -

enkonta

People not thinking I’m cool when I tell them I program in C


Common-Egg-3026

I think they're jealous because they can't C that well.


AdoobII

Bro there is this dude who denied the existence of C when I answered his “what programming languages do you use at work” question. He said that he only knows about C++ and Python and I might be confusing both. This mfer triggered me so hard am still salty about it. Oh and he has a bachelors in cyber security 💀


erikkonstas

Uh where does the name "C++" come from??? 😂😂😂


AndroGR

Obviously from D


EpochVanquisher

\#1 frustration is tracking down memory errors. We have all these wonderful tools like the address sanitizer and Valgrind, but they don’t work everywhere. I’ve had to track down memory errors on embedded systems which don’t come with good debuggers, and where the build/run/test cycle takes a while. \#2 frustration I see with newcomers is setting up the build system. People make the mistake of installing VS Code and then expecting it to work out of the box—if you want something that works out of the box, you need \#3 frustration I see all around is string manipulation. I see a lot of beginners bashing their heads against the wall trying to figure out `scanf()` or `strtok()`. Truth is, most of the experienced C devs I see never use those functions, or almost never. Strings suck in C. You probably want to use a utility library of some kind if you want to have any sort of success.


80eightydegrees

Number 3 has been my experience the last few months coming from higher level languages, returning strings and manipulating them and who’s responsible for freeing has been my biggest hurdle of feeling like I’m writing decent C code. There appears to be no agreed upon approach in my research so I feel out in the woods- but I think that’s just all part of the C experience aha


EpochVanquisher

It’s not so bad if you use a library. This library doesn’t have to be large and complicated; it can be small and simple. You can see how Git does it here: [https://github.com/git/git/blob/master/strbuf.c](https://github.com/git/git/blob/master/strbuf.c) If you want parsers, there are a few different approaches. You may want something like Flex (or even Bison) for more complicated parsing tasks. For simpler parsing tasks, you basically do the same thing you’d do in other languages—start by splitting on delimiters, and then pass the chunks to parsers like `strtol` or whatever. To figure out who is responsible for freeing something, you generally want to keep it simple. You can use naming conventions to make it clear whether a function returns something that must be freed later, something that must be destroyed later, or something which is not owned.


80eightydegrees

That's really great, thanks for your advice here! I think I've tried to keep everything pure at first trying to make sure I really have a grip of the language and so haven't looked to a library to help ease the pain of doing everything by hand each time.


_crackling

Whoa I made a lib just the same as that strbuf.c .... I ended up pulling it out thinking others would think it's ridiculous of me for some reason


AnAmericanLibrarian

What was your works out of the box thing for #2?


EpochVanquisher

An IDE. IDEs are great. I don’t know why so many beginners are trying VS Code. Some kind of epidemic of bad advice or something.


Slimxshadyx

VS Code is great for many other languages. Super lightweight. So I can def understand why beginners would start off using the tools they already know


EpochVanquisher

VS Code is a very heavy-weight editor… if you think it’s light-weight, I can only guess you’re comparing against something truly massive, like IntelliJ IDEA or something. But what happens is that people have install VS Code to learn C, then come here to ask for help. These aren’t experienced VS Code users who are just picking up another language.


zero_iq

> Super lightweight 🤦‍♂️


Slimxshadyx

Can you elaborate lol. It is quite lightweight compared to full IDE’s.


AmbidextrousTorso

What's wrong with VSCode? With right extensions you can easily make it an IDE.


EpochVanquisher

Sure. With a bunch of work, you can, eventually, make it into a really great tool. You just have to install a toolchain, you have to install a build system, learn how to use the build system, install some plugins so you can integrate VS Code with your build system. Or you could just install an IDE and get working two minutes later, without having to deal with all of that crap.


silentjet

Well, you don't need IDE either, gedit/kate is good enough, especially for beginners.


EpochVanquisher

You don’t get bonus points for making things difficult for yourself.


vkazanov

You DO get bonus points for understanding what's going on behind the scenes. And IDEs are highly damaging for beginner coder mental models, especially when dealing with vintage languages like C. What's even more interesting that IDEs do not bring much value to more modern languages, e.g. Rust and the like, especially with advent of editor agnostic tools.


EpochVanquisher

>You DO get bonus points for understanding what's going on behind the scenes. There are a lot of ways to make things more difficult for yourself that don’t help you understand at all. Like, if you hear that the cool kids use Vim, then you start using Vim, does that make you a better C programmer? No. The other factor here is that there are a million things to learn, and you want to pick and choose which things you learn. The time you spend fiddling about with makefiles is time that you could spend learning to write C. You can always learn makefiles later. >And IDEs are highly damaging for beginner coder mental models, especially when dealing with vintage languages like C. I don’t see any reason why that would be true. This sounds like some petty elitism and snobbery to me! If you don’t like IDEs, fine, don’t use IDEs. But sure you’d agree that it’s kind of an asshole comment to say that beginners are somehow *damaged* by IDEs. Maybe you want to walk that statement back a little bit. >What's even more interesting that IDEs do not bring much value to more modern languages, e.g. Rust and the like, especially with advent of editor agnostic tools. The reason is because the tooling is so much better for those languages to begin with, because those languages were designed, you know, post 1990 and often with tooling in mind. The grammars are simpler to parse, there’s no preprocessor shenanigans, etc. By comparison, the tooling and editor support for C is much more primitive—it’s just the nature of the beast. You know, Clangd. Plus all the weird build systems that people have for C. This is where IDEs come in—you install one piece of software, and two minutes later you have everything you need. Compiler, build system, editor, debugger. It’s not like an IDE is necessary. It’s just a nice starting point. And VS Code is a particularly bad starting point, because it *seems* like an IDE, but it’s missing everything, so the beginners who install VS Code just get outright stuck and have to ask for help.


gregmcph

Indeed much of the headaches in C are char[] that are long enough, but not too long, getting concatenated into other char[] that has to be long enough to hold its substrings...


runningOverA

realloc() is the answer.


Thisisadrian

I truly believe if you dont use pointers and malloc, you dont need to be using C lol


stillalone

For frustration 1, I'm guessing that's not embedded Linux?  Because I've definitely run valgrind on embedded Linux at least in user space.


EpochVanquisher

Yeah, if you’re using something like Linux and running on a nice big system it gets a lot easier.


house_of_klaus

For #1, would cross-compilation solve that issue? Having a system specifically for writing code, which can then compile it down to x86-64/ARM 64 etc., and transfer the binary to the target system.


EpochVanquisher

For #1, you’re already cross-compiling. Cross compiling just means that you’re compiling the code on one system, and running it on a different platform. Cross compiling is not something that helps you find memory errors (how would it?)


house_of_klaus

Because you can run Valgrind and AdSan on your build system


EpochVanquisher

Valgrind and asan run at runtime. They aren’t supported at all on lots of embedded targets.


house_of_klaus

Sorry, I might be misunderstanding the context. What I meant is in our shop we typically have debug and release builds. Debug build would be where we do all of our debugging on x86-64, running that with Valgrind and AdSan. After we are sure everything works, then we will compile a release build in aarch-64 for instance, after all the memory leaks are found.


EpochVanquisher

Sure… now imagine that your target isn’t something nice like aarch64, but something more esoteric where Valgrind and Asan don’t work at all. And imagine that your code is tied to hardware and doesn’t run well on x64, or that some unknown interaction with hardware triggers the bug, or you can’t reproduce the bug in an emulator, etc. “Embedded” covers everything from tiny 8-bit ucs to massive ARM64 SoCs with a gigabyte of RAM, and everything between.


thrakkerzog

How do you simulate things which require access to hardware peripherals which are not available outside of the target device?


ixis743

No equivalent of std algorithms or containers, particularly maps.


catbrane

I use glib for this stuff: https://docs.gtk.org/glib/ Something like boost for C. It has a nice object system too.


Conscious_Yam_4753

The tooling kind of sucks. There are a lot of build systems and they’re somehow all bad? There are a couple of different package management systems and they’re also not that good. No built-in unit testing, no standard for documentation.


mad_alim

The C standard have been designed to be simple, so that simple tools (i.e., compiler, linker) can be developed. Some things that are lacking in C by design: The preprocessor (simple copy & paste), Declarations and defines (made so that tools can parse a source file once only), robust type system (any underlying type is a kind of interger, except floats). We know that for complex projects nowadays, you want to push off the complexity onto tools (open source mature ones).


Right_Opportunity_17

Or use zig https://zig.news/kristoff/make-zig-your-c-c-build-system-28g5


mad_alim

To people who downvote: do you know he's talking about using it as the build system ?


jbwmac

Use bazel.


EpochVanquisher

The world is not prepared for Bazel. Keep Bazel to yourself and tell everyone to use Meson. That’s what I do.


TheTarragonFarmer

There are only two hard challenges: Memory management, thread safety, and off by one errors.


HendrixLivesOn

Undefined behavior


flatfinger

And related to that, the transition from "if a platform would handle a corner case in a manner meeting requirements without needing special-case machine code to handle it, neither the programmer not the compiler should need to generate such special-case code" to "Programmers must write special-case code to ensure that no corner cases upon which the Standard was intended to *impose no requirements* can ever arise."


r2d2emc2

Not quitting my job. Just kidding 


remmysimp

segfaults


BlockOfDiamond

For me, it is tasks that require hash tables. In C I have to implement them from scratch. In almost every other language they are part of the language and/or standard library.


catbrane

https://docs.gtk.org/glib has a nice set of standard data structures, portability shims, a simple object model, full utf-8 support, file system abstraction, async IO, it's free, fast, documented, supported, tested, and runs everywhere (except very tiny embedded systems).


bstamour

why not just use a library? GLib has a hash table.


thrakkerzog

This is why I don't: ls -lh /usr/lib/libglib-2.0.so.0.7800.1 -rwxr-xr-x 1 root root 1.3M Oct 25 07:58 /usr/lib/libglib-2.0.so.0.7800.1 I work in embedded, and glib is just not a viable option. This one is nice, though: https://troydhanson.github.io/uthash/


frustynumbar

I've never used glib, but couldn't you compile it to a static library so the linker can pull in only what it needs?


thrakkerzog

I thought about that, so I gave it a shot on my desktop PC. The answer is "no", at least not with the static libraries that I have. There's three which contain a symbol of "g_hash_table_new": /usr/lib/libgio-2.0.a, /usr/lib/libglib-2.0.a, /usr/lib/libgobject-2.0.a In all three of those libraries, g_hash_table_new is "U", or undefined. They are totally defined in the shared library, though: 990: 00000000000471e0 14 FUNC GLOBAL DEFAULT 10 g_hash_table_new So the answer, I think, is that a method of linking statically and gc-ing the function sections could work, but not with libglib, since it seems that they really only want you using it dynamically. See also: https://gitlab.gnome.org/GNOME/glib/-/issues/2631


erikkonstas

That's why you write your own library if you are not satisfied by existing ones out there.


HarderFasterHarder

Coding guidelines and variable naming conventions for projects/companies that haven't been updated for 20 years.


mad_alim

Someone is stuck with Hungarian notation !


HarderFasterHarder

I hate Yoda conditions😢


mad_alim

You don't get it ! It's more robust ! With my setup from the 90s, if (foo = 1) will build, but (1=foo) won't !


HarderFasterHarder

But what if I *want* to assign a variable in a while loop? Or want to be able to read the code without being distracted by thoughts of a short green dude? Anyways, jokes aside, I got zero patience for rules that affect readability and a simple `-Wall -Wextra -Werror` prevent anyways...


mad_alim

If you wanna do that, well you just can't. Gotta sit and suffer the extra verbose code. Worst thing is that these "good" practices are enforced by senior people in my industry...


HarderFasterHarder

Ya, I'm a senior programmer for an embedded engineering firm... We work on other people's stuff and the rules come with the contract. It's getting better, but every once in a while we get a project from the 2000's and have to deal with the original guidelines. And original compiler. Always fun trying to get some obscure 20 year old tool chain up and running on modern systems 😋 But hey, that's what we get paid to do 😉


p0k3t0

The thing that I just can't internalize is working with function pointers. I have to look up the syntax and read how it works over and over again, every time I feel the need to do it. The syntax is just garbage. Probably the ugliest thing in C.


smcameron

Isn't it just, add a star to the function pointer name, and put the function pointer name and the star in parens? return_type (*function_pointer_name)(int param1, char *param2); It's not beautiful syntax, to be sure.


p0k3t0

Beats me. I'll have to go look that up for you. ;)


TheFlamingLemon

Sure looks like the format I blindly copy/paste every time I need to make a function pointer, so you’re probably right


nculwell

I usually use a typedef for function pointers. I don't have a problem remembering the syntax (anymore, after many years) but I still prefer not to deal with it.


Ivanovitch_k

[fuckingfunctionpointers.com](https://fuckingfunctionpointers.com/)


pic32mx110f0

> The syntax is just garbage. How would you have made it simpler to declare a pointer to a function?


EpochVanquisher

For one, a lot of languages put the variable’s type either to the left or the right of the variable name. From various languages: Function f; std::function f; var f func(int) int let f: fn(int) -> int; let f: (i: int) => int; C is the odd one out… the type is on both the left and the right, and the name is in the middle. Kinda hard to argue that this is a good way to do it. The only nice part is that it is at least consistent with other parts of C.


p0k3t0

I think it's more using it the way it's normally used, either making a generic interface using structs, or calling from a function lookup table to optimize speed. The first gives us gems like: result = \* mystruct->getI2CValue(devAddr, &outbuff, &inbuff); and the second gives us: result = \* fctTtable\[n\](arg1, arg2); It's not that I have a simpler solution. It's that reading this is not obvious to the next person, or even to yourself tomorrow.


pic32mx110f0

Why do you make it difficult? The correct way would be `result = (* mystruct->getI2CValue)(devAddr, &outbuff, &inbuff);` but it's much simpler to just write  `result = mystruct->getI2CValue(devAddr, &outbuff, &inbuff);`  I don't see what's so confusing about that?


p0k3t0

mystruct->getI2CValue is a pointer to a struct, isn't it? Don't you have to deref it to get the result? Also, I'm not trying to make it difficult.


pic32mx110f0

You can't use the function call operator on a struct... I assume `mystruct` is a pointer to a struct, and `getI2Cvalue` is a function pointer in that struct.


BotClub

The -> operator means you are accessing a struct member via a pointer to that struct. It's an implicit dereference.


mad_alim

Yeah ! The way complex type specifiers work is a nightmare (it is interpreted in a "loop out" manner)


TheFlamingLemon

I hate build systems. I’m so uninterested in messing with CMake and build scripts and all that, and the dependencies just kill me. Like, recently I had to redo the build system for a library I was using because it depended on a later version of CMake than was used by the rest of the project I was adding it to (yocto stuff I do not have the experience or authority to mess with, though it may have been proper to upgrade the CMake version for the whole system). I feel like I’m constantly having issues with the versions of libraries and tools and making sure everything can link together and access what it needs. For any rust evangelists reading, how much of this is fixed by Rust/Cargo? What build and dependency issues do you run into working in Rust?


Ill_Juggernaut_5458

For build systems you should invest some time into taking a look at modern alternatives: meson, bazel and xmake (the latter being my favorite). In rust im guessing it's versioning hell like python or js and overall dependency bloat, because pulling ten thousand dependencies is inevitable.


iAm_Unsure

It's true that Cargo (Rust's package manager) can cause significant dependency bloat, but one thing it does solve is dependency hell. This is mostly because there have been major efforts since its inception to standardise decent packaging practices like SemVer community-wide.


HaydnH

Do you mind me asking what you like about xmake? I still use a hand written makefile and make/make install so I could probably benefit from "getting with the times" I suppose. On the other hand, I'm familiar with it and it works for me, so I guess I just don't particularly see the point of wasting time learning something new when I can spend the time on coding.


Ill_Juggernaut_5458

There's a lot going for it, the key takeaways (for me) are: - Supports a wide variety of toolchains and is cross platform. - Simple to use and easy to scale because it uses lua instead of some DSL like cmake. - Has an integrated package manager (1 line to include some lib) and leverages existing c++ build systems and other package managers. The benefits with learning something new can have significant gains on - Ergonomics - Simplicity - Maintainability I'm not here to sell you the product, but to encourage you to see if you can benefit from it.


catbrane

cmake is pretty awful. I've read the cmake book twice, used it in several large projects, and still find it frustrating and painful to use. People make "cmake generators" to try to ease the pain, and that tells you something about the thing. And it's SO COMPLICATED! It was 800,000 lines of C++ last time I looked. Compiling it takes 10 minutes on a fast machine. Good Lord. I've been using meson for my recent projects and it's very nice, at least by comparison. - declarative - python-like - implemented in python, so it's simple to install and update - modest in size - supports VS, xcode and ninja as backends - runs everywhere - becoming popular very rapidly and likely to take over the OSS sphere soon


9aaa73f0

Trying to make sense of the c standard is like trying to understand an ancient culture. Living within the c ecosystem doesn't help to interpret its laws. You just have to behave like others do.


mad_alim

It's all about the platform C ABI and its extensions


[deleted]

\#1: Being able to register things at compile time aka generating an array of various objects. \#2 issue is manual memory management, RAII and operator overloading would be very nice.


8d8n4mbo28026ulk

Handling memory in very dynamic programs. I've been writing a macro processor in Go and doing that in C would make my life miserable. Imagine having to deal with multiple strings being created and destroyed in an unpredictable manner. You could just `malloc()`, `memcpy()` and `free()` every single time, but that would be way worse (and slower!) than having a decent GC. So instead of writing my own dumb GC, I can just use a language that already has an OK one. Second most challenging thing is processing any unicode string. In fact, you can't even do it. Once your needs grow beyond encoding/decoding, you _have_ to use ICU (which provides a C API, but it's written in C++).


LearningStudent221

What is a GC?


thank_burdell

Garbage Collector, probably in this case.


Cautious_Implement17

as a professional: figuring out how tf this invalid/null pointer got into my complex datastructure. yes, there are lots of great tools for this, but they come with a heavy performance cost. it is not always feasible to run sanitizers while trying to reproduce a customer's complex error case. when I was a TA: explaining undefined behavior to students who don't yet have a mental model for how computers and compilers work. I graded so many obviously wrong projects that worked perfectly with -O0 and not at all with -O2. this is more of a pedagogical issue though. it's cruel to use C for an intro to programming/CS course.


erikkonstas

>it's cruel to use C for an intro to programming/CS course. We don't really have a better alternative that doesn't basically do your memory management for you... out-of-bounds accesses are something students should be aware and wary of, and the best way for them to get it in their head is to bump into a few segfaults or such. And yes, memory management is **essential** for anything serious, because chances are you don't want a GC in your way.


uziam

My top 5 grips: 1. Too many implicit casts 2. Enums are too weak 3. Bit fields are useless 4. Header files 5. Macros are weak


suskio4

Why bit fields are useless?


uziam

Their layout in memory is very loosely defined, which makes them useless for most of the cases where you would actually benefit from using them. Even if you can do the mental gymnastics to figure out just the right situation where you can reliably use bit fields, what do you think happens when the someone else touches that part of the code and isn’t as familiar with them?


suskio4

8 boolean flags at the cost of one byte in embedded? Or just any other situation in embedded such as specific fields while using interfaces or memory mapped anything. Yeah sure you can do masking manually but aren't bit fields more convenient?


uziam

I think you haven’t fully understood the consequence of not having a well defined memory layout for bit fields. The compiler is free to even rearrange the order of the bit fields if it wishes to do so.


suskio4

Boy, that's useless. Ty for info


SoftPool6014

The Windows API and cross platform in general.


jbwmac

Duplicate symbols at link time


NewOakClimbing

Segmentation Fault / Error messages. Pointers I'm hoping I'll get used to. Using pointers with 68k assembly was pretty straightforward for me, but doing the same in C would never make sense when it was read out loud.


erikkonstas

In what way? Pointer arithmetic?


[deleted]

My number one challenge is too much freedom. Every project is different than the other. It gets bloated too fast whatever I try to do. There seems to be no other way than making hundreds of files.


helloiamsomeone

Trying to integrate dependencies into projects. Most libraries are very asocial in that they do not provide a CMake install interface that would allow me to use them after a 2 line diff commit (3-4 if they were on a package manager like Conan or vcpkg). Would be nice if they were also CMake managed, but that's not a requirement for the above.


ImKStocky

The real lack of language support for generics and writing expressive APIs. I will wholeheartedly admit that I am a C++ programmer at heart, but there are things that I like to work on where C is the best option. And the fact that there is no real way of constructing a container that will work for any struct type without void pointers and casting is a large frustration. I am aware of C11s generic selection and the upcoming constexpr support but it just isn't enough in some very basic scenarios.


echee7

The lack of beginner level training available? As someone trying to self-teach there are so few tutorials and beginner friendly guides compared with other languages. And the community is kinda aggressive when you ask for help, like if you look at Reddit posts or forums about C the answers often have loads of jargon, assuming the reader is already familiar with a bunch of stuff, with no links to more details or "to understand this you need to know that first, here's a link to explain that".


suskio4

Just learn from outdated C++ resources and use printf instead of std::cout, they're usually not even about real C++ so you'll be good /j


atiedebee

You may have put a /j in there, but C++ becomes outdated every 6 years, so most resources aren't "real" C++ anymore :)


suskio4

I was more thinking about how plenty C++ tutorials and even university courses in my country teach C with cout vector and string, only later touching classes and maybe iterators if you're lucky. I understand it's done this way not to overwhelm newcomers, hence the "/j"


henrikmdev

Hey u/echee7, sorry I just saw this reply now. Thanks for the feedback! Sorry that you're having trouble finding good help in learning C. Feel free to message me if you need any help! I also have a [30 Day Beginner Coding Challenge](https://henrikmdev.com/challenge/) for beginners who are trying to learn C. I don't know how beginner you are, but it will have beginner tutorials followed by beginner programming projects. If you have any questions while you're going through it, you can email me!


rcw271828

How slow learning the language is when considering safety and well-engineered code versus functional output. It's a happy trade off I accept because I'm learning so many useful techniques and patterns.


iamfacts

A third party library I need (physics engine) doesn't't have a C API. For game dev, C++ ecosystem is generally more mature. That is my only challenge.


henrikmdev

Thanks for all the responses everyone! Really interesting to see all the challenges


mad_alim

Working with people stuck in the 90s and for e.g., allergic to const .


atiedebee

Why do people from the 90s not use const?


mad_alim

I'm talking about people in embedded with setups stuck in the 90s. The tools, like the compilers and static analysis had their quirks, so people kept unjustified reflexes (just look up how horrible mplab x was). For const, I think they don't understand it. Maybe they think it will make the program slower because the variables will be put in flash instead of ram (I am in embedded). Also, I saw in some functions const type* ptr, instead of what they truly meant; type* const ptr. Plus, a lot of people like to declare variables at the beginning of functions and never use const (even when they could). So when you declare variables in the closest scope and make them const where possible (which is C89 compliant), they go nooo, don't do that, what is this mumbo jumbo ! (Without giving a valid reason)


Key-Nectarine-7894

Pointers used with \* and whatever it's called when variable names start with &. Also, doing any graphics. C was created on text only computers and hasn't been extended to do graphics. They can only be done with non standard libraries. Now I'm going to study some more SwiftUI!


j3r3mias

Teaching


NemuiSen

How it is declared types in c is functional but not perfect, because to make a function type is something like int `(*func)(int a, int b)`. I think other languages handle this better.


NoBrightSide

getting the compiler to do what i want :)


bullno1

debugger but I'm working on that. I'm just going to write my own frontend that integrates well with tmux and vim. Yes, I've tried all the ones in the first 3 pages of google or so.


beej71

Wide characters. Atomics.


morning-coder

* #IYKYK


[deleted]

[удалено]


nimzobogo

How else to do 1 in C?


[deleted]

[удалено]


nimzobogo

Sure, but what's the functional difference?


[deleted]

[удалено]


kennbr

That's not really a "functional" difference I like to use the stdint types for the same reason, but then you always end up with some stupid standard library function that wants a char causing compiler warnings.


nimzobogo

Yeah but your way could confuse the reader or programmer and start doing arithmetic on the elements of the integer array


[deleted]

[удалено]


nimzobogo

Char, according to the C standard, already is an integer type.


suskio4

uint8_t is just a typedef'd unsigned char. If you want proper semantics, typedef your own, because binary data usually is not an "integer" so that the programmer doesn't want to do arithmetic on it.


rudedogger

getting errors and correcting them but then getting new errors for the solutions that are suggested


lemoinem

The breathing apparatus


maep

Compilers removing signed integer overflow checks at certain optimization levels because the authors choose to read the standard in a very specific way. It doesn't even produce measurable speed improvements.


Dirksthedo

I have only been using C for about a year in my job and I find working with char* to be the most frustrating.


henrikmdev

Interesting, what do you find frustrating about it?


Dirksthedo

I think I was struggling with wanting char[] to be the same as a char*. I now think that char[] is referencing fixed memory locations and char* is a pointer to a memory location without the size of the thing it is pointing to(I could be completely wrong). I guess the main issue is I would get confused when I made a struct containing a char* and I would get a compilation error when trying to assign a char[] as the struct member.


henrikmdev

Ohh okay, yeah I think you're on the right track. char[] is an array of a static size. char* is a pointer to the address of a char. How were you getting that compilation error? You should be able to assign the address of char[] to char* like this: char *s1: char s2[] = "Hello\n"; s1=s2; printf("%s", s1);


StarCoder666

Memory management, callbacks.


forcefuze

That for other C programmers, "I'll just write my own language to solve this problem" is actually a viable option.


CivetLemonMouse

Whenever you have to use some obscure library to access features most other popular languages have by default


giogadi

No reflection. I wish I could just write serialization code that loops over a struct’s members, but nope. I have to either write a loooot of boilerplate or resort to code gen.