3 ms·
> and I end up having all these typedefs in my projects I avoid doing this now. It's more trouble than it's worth and it changes your code from a standard dia
by themafia 9mo ago
> and I end up having all these typedefs in my projects
I avoid doing this now. It's more trouble than it's worth and it changes your code from a standard dialect of C into a custom one. Plus my eyes are old and they don't enjoy separating short identifiers.
> typedef struct { ... } String
I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling. C23 finally gave us "auto", you shouldn't fret over typedefing everything anymore. I also prefer a "strbuf" type with an index and capacity so I can safely read and write to it with a derived "strview" having pointer and length only which references into the buffer.
> returning results
The general method of returning structures larger than two machine words is fairly inefficient. Plus you're cutting yourself off from another C23 gem which was [[nodiscard]]. If you want the 'ok' value checked then you can _really_ specify that. Put everything else behind a pointer passed in an argument. The sum type logic works just as well there.
> I tend to avoid the string.h functions most of the time, only employing the mem family when I want to, well, mess with memory.
So you use strlen() a lot and don't have to deal with multibyte characters anywhere in your code. It's not much of a strategy.
- apaprocki 9mo ago> > typedef struct { ... } String > I avoid doing this. Just use `struct string { ... };'. It makes it clear what you're handling. Well then imagine if Gtk made you write `struct GtkLabel`, etc. and you saw hundreds of `struct` on the screen taking up space in heavy UI code. Sometimes abstractions are worthwhile.
- wavemode 9mo agoThe main thing I dislike about typedefs is that you can't forward declare them. If I know for sure I'm never going to need to do that then OK.
- procaryote 9mo agoHow do you mean? You can at least do things like typedef struct foo foo; and somewhere else struct foo { … }
- flohofwoe 9mo agoThe usual solution for this is: typedef struct bla_s { ... } bla_t; Now you have a struct named 'bla_s' and a type alias 'bla_t'. For the forward declaration you'd use 'bla_s'. Using the same name also works just fine, since structs and type aliases live in different namespaces: typedef struct bla_t { ... } bla_t; ...also before that topic comes up again: the _t postfix is not reserved in the C standard :)
- apaprocki 9mo agoYes, using the same Gtk example, the way you’d forward declare GtkLabel without including gtklabel.h in your header would be: struct _GtkLabel; typedef struct _GtkLabel GtkLabel; // Use GtkLabel* in declarations
- 1718627440 9mo agoWhy are you complicating things? Struct and Unions are different namespaces for a reason. typedef struct GtkLabel GtkLabel; works just fine.
- apaprocki 9mo agoI’m simply stating how actual Gtk is written: https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel.h#L39 https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtklabel....
- 1718627440 9mo agoTrue, thanks then. As far as I see it they don't even use the struct in the implementation, so I guess it makes some sense.
- warmwaffles 9mo agoPeople getting hung up on `_t` usage being reserved for posix need to lighten up. I doubt they'll clash with my definitions and if does happen in the future, I'll change the typedef name.
- lelanthran 9mo ago> Well then imagine if Gtk made you write `struct GtkLabel`, etc. and you saw hundreds of `struct` on the screen taking up space in heavy UI code. Sometimes abstractions are worthwhile. TBH, in that case the GtkLabel (and, indeed, the entire widget hierarchy) should be opaque pointers anyway. If you're not using a struct as an abstraction, then don't typedef it. If you are, then hide the damn fields.
- f1shy 9mo agoThank you! Because I wanted to point exactly that. When I was very junior programmer, and coded alone, I used to have “that elemental header” where lots of things were inside. Many of them to convert C in what I wished it was. Now I think is between no good idea, and absolutely awful. Yes, sometimes you wish some thing were different in a programming language “if only these types had shorter names”. But when you work in a team, first you should have consensus, and then modifying the language becomes a heavy load, that every new person in the project will have to lift. “Modifying C is porting the Lisp curse to C” is my motto. Use all as standard, vanilla as possible.
- lelanthran 9mo ago> So you use strlen() a lot and don't have to deal with multibyte characters anywhere in your code. It's not much of a strategy. You don't need to support all multibyte encodings (i.e. DBCS, UCS-2, UCS-4, UTF-16 or UTF-32) characters if you're able to normalise all input to UTF-8. I think, when you are building a system, restricting all (human language) input to be UTF-8 is a fair and reasonable design decision, and then you can use strlen to your hearts content.
- lionkor 9mo agoAm I missing something here? UTF8 has multibyte characters, they're just spread across multiple bytes. When you strlen() a UTF8 string, you don't get the length of the string, but instead the size in bytes. Same with indices. If you Index at [1] in a string with a flag emoji, you don't get a valid UTF8 code point, but instead some part of the flag emoji. This applies with any UTF8 code points larger than 1 byte, which there are a lot of. UTF16 or UTF32 are just different encodings. What am I missing? That's why UTF8 libraries exist.
- lelanthran 9mo ago> When you strlen() a UTF8 string, you don't get the length of the string, but instead the size in bytes. Yes, and? > What am I missing? A use-case? Where, in your C code, is it reasonable to get the number of multibyte characters instead of the number of bytes in the string? What are you going to use "number of unicode codepoints" for? Any usage that amounts to "I need the number of unicode codepoints in this string" is coupled to handling the display of glyphs within your program, in which case you'd be using a library for that anyway because graphics is not part of C (or C++) anyway. If you're simply printing it out, storing it, comparing it, searching it, etc, how would having the number of unicode codepoints help? What would it get used for?
- tialaramex 9mo agoIndeed. If you have output considerations then the number of Unicode codepoints isn't what you wanted anyway, you care about how many output glyphs there will be, that codepoint might result in zero glyphs, it might modify an adjacent glyph, or it might be best rendered as multiple glyphs. If you're doing some sort of searching you want a normalization and probably pre-processing step, but again you won't care about trying to count Unicode code points.
- JKCalhoun 9mo agoI was going to comment the same thing. I had a coworker who had a very complicated set of "includes" that their code relied upon—not unlike the typedefs in the post. So his code was difficult to move around without also moving all his headers with it. I try to minimize dependencies (custom headers, custom macros, etc.).