I've looked to some open source Libraries in some places. And, I've realized which that Libraries are basically a great stack of structs. I've seen few methods.
Why does C written libraries uses so much structs? What's the basis behind this? This, for me, looked like a attempt to simulate object orientation, 'cause a fast searching told me that each struct is "instantiated" by the using program to make something, per example, in some Desktop enviroments for linux that I've seen that each window was a struct in the used GUI library.
Anyway, the question is that.
Structs are a great way to organize data. And data is fundamental, as Fred Brooks knew decades ago:
Show me your flowcharts and conceal your tables, and I shall continue
to be mystified. Show me your tables, and I won't usually need your
flowcharts; they'll be obvious.
Object-oriented programming doesn't have to be merely simulated in C, it can be realized. For example, did you know that inside your structs you can store function pointers which operate on those same structs, and then you are a little bit closer to C++'s classes?
Also consider extensibility: even a function taking many arguments may be improved by taking a single struct, because then its signature does not need to change when a new argument is added.
Finally, C does not have multiple return values from a single function call. But it can return a struct, which is about the same thing. C is a lot about building your own tools from the raw language, and being able to stash a bunch of related data and/or functions together in one place is a good building block.
With or without object orientation, structures are a useful way to group aggregate data into a single symbol. You can copy the structure wherever you like without having to write out all the members each time, and this makes the structure easier to change if you have to.
It also makes it easier to reference certain members using pointer arithmetic, if you're careful (see sockaddr).
Same argument as with arrays.
Simply put, there's no reason not to use structures.
Structures are useful while retrieving data using a pointer. Because single pointer is enough for complete bunch of data with in a structure.
One, it keeps the APIs clean. Instead of passing N separate arguments to a function, you pass a single argument containing N members.
Two, it allows the library to hide implementation details from the programmer. For example, the C FILE type abstracts away some details of stream I/O, details which vary from implementation to implementation. We don't need to know those details, so they're not exposed to us; we just use the FILE type to pass that information around.
Related
As stated in the title, what is major difference between GLib.Array and GLib.List in Vala language? They look very similar in the tutorial pages.
GLib.Array is an array. GLib.List is a (doubly linked) list. Here is an article comparing (singly linked) lists and arrays: https://www.geeksforgeeks.org/linked-list-vs-array/
It's also worth mentioning that with GLib.List (and GLib.SList), the pointer actually points to the head of the list. That means that if you're storing a reference to the list in one place and modifying the list somewhere else you'll likely end up with some memory management problems. Unless you understand what's going on under the hood you're probably much better off using Gee.List (or one of the other data structures in libgee).
In Vala you'll generally want to use GLib.GenericArray instead of GLib.Array, unless you're interfacing with something which requires a GLib.Array. GLib.Array just doesn't work quite as well with how generics work in Vala; GArray is actually a bit weird in C as well, and just doesn't translate very well to Vala. GLib.GenericArray is an alternate binding for GLib.PtrArray (which is a GPtrArray at the C level, not a GArray).
Apart from the obvious difference that the first deals only with arrays, don't they do the same thing? I keep reading the help pages for the two functions, and can't understand when should I use one over the other and why. Internet search seems to indicate only the second is used whatsoever for array copying purposes if not written using loops.
System.Copy is really compiler magic. It's applicable both to strings and to dynamic arrays.
Compiler chooses needed version of intrinsic routine (different for short strings, long strings, dynamic arrays) and substitutes your call of Copy.
For dynamic arrays _DynArrayCopyRange prepares memory, provides reference counting, and calls System.CopyArray for deep copy of elements.
Usually you don't need to call the last procedure expicitly, it is compiler prerogative.
So I've run into an interesting design pattern and I wanted to know if you guys had an opinion on it.
Basically, the design is passing everything around as a pre-serialized type. There is no "types" for the returns, for example. It is passed as a simple uint8_t*. There is a defined header that "tells" you what is in the buffer, how big it is, what the version of the buffer is, ect. I call it "pre-serialized" because it forces flattening of all structures.
The pros:
You can easily write it (or even a set of it) to what ever you want. Files, IO, whatever.
Can store arbitrary data.
The Cons: IMHO:
No type safety is going to be a nightmare
The programmer has to parse the code. Even if there is an enumerated type, the user would have to know what that type means. Even if there are functions to parse the type, the programmer has to know that is the function to call.
Version hell: changing code will cause a ripple effect of errors. Because everywhere is parsing it differently, you have no idea where the code works or where it is broken.
It is viral: because it is flat, you can't "insert" the header on the end of outside data. You could wrap the call if you copy your "data", but this could cause an unnecessary copy that would be SLOW. So either your code is slower than it needs to be, or you conform to this data structure.
It isn't human readable OR debug-able.
Have you seen this design pattern before? Is there a name for this design pattern? Things I missed?
Is there a name for this design pattern?
Well, Legacy Code? :) I have seen such design in 30 years old Cobol systems...
The pros you have stated are easily reachable also by using XML format (or JSON):
You can easily write it (or even a set of it) to what ever you want. Files, IO, whatever - most of all, web services!
Can store arbitrary data.
Furthermore, all your cons are eliminated.
The only pro I can see in your solution is conciseness - when every byte counts and you need to avoid any overhead as too expensive, then this is nice.
Added: Cobol has a feature to easily define the structure of such serialized data, see PICTURE clause. Reading the data is very easy then, you read them as variables. (Like if you have a binary data and define a struct in the C language and typecast the binary to the struct.)
As Honza said this would be normal in Legacy Cobol/PL1 (was there a Cobol/PL1 conversion or interface to COBOL programs ???).
In COBOL this design pattern would make sense, not sure about C though (one of the binary serialization packages or JSON etc might be more sensible).
In Cobol, you would have a Cobol copybook which all programs would use and could edit the data using the Cobol Copybook (with something like file-aid or Microfocus Data Editor).
Why use this "design pattern" in Cobol:
Regression testing of Modules; you can write a driver module like
Read Test-data-file
while more-data
Call Module
write Result to output-file
Read Test-data-file
end
You can then do a compare between Output from the
re-Change Program to the changed program.
Testing - some times you can use a "production file" in testing
A file provides trace or snapshot of what is going on, this can be very useful.
Easy to reorganize Batch streams:
Split a programs up (and pass the data via file). There variety of reason for doing this including
program has gotten to big and is hard to maintain.
Sorting the data
Performance (use a file rather than hitting the DB multiple times)
new uses for extracted data
While your cons are valid for C, they will be less of an issue in Cobol.
The key to using this "design pattern" is being able to edit/view/compare the format. If you can not edit/view/compare a file, I do not see the point
I have a quick question when programming in C. I am writing a simple application in C as the title suggests but i find myself defining rather large functions in separate source files so it makes maintenance and debugging much easier but my question is is there a standard X amount of lines in a c source file before you should "split" it up into multiple files or is it very dependant on the system/functions in question.
Say for example i have 20 source files with 1 function in each say the functions are somewhat related but they all do different things (e.g. they all manipulate the same struct in some way) should you in theory have these 20 files, or 1 larger file with 20 functions and keep the modification of X structure in the same file?
My idea is the more "split" the better/easier the coding becomes, but then again im quite new to C.
Any input will be appreciated.
Cheers,
Chris.
It makes sense to put code related to the same conceptional area together. If you have functions which work on matrices for example, it would seem to make sense to have a file called matrices.c within which, there are X number of matrix functions. A function called render would obviously not belong there.
Yet if the number of matrix function were to grow huge, it started to feel wrong to shove them all into a single file. Under such a situation I would look for sub-categories and create separate files for each, e.g 2d_matrix.c, 3d_matrix.c, etc.
As for the number of functions you place in a file before you recategorize it, that's is up to personal choice and sometimes development rules of the team you work for.
The same consideration sometimes applies to the size of a function. One team I have worked for would not allow code which is over two screens high, feeling that such code should be broken up into a number of smaller functions which would make the code more readable.
To me, structure your code in a way that makes sense. Keep related code together and be sensible with sizes of functions, number of functions in a file (both too few or too many).
The larger a function gets, the more easy it is to accidentally break it.
The more code you shove in one file, the more likely it will be for other people to be a little sloppy and shove more, and possibly unrelated code in the same file.
Splitting up of a file is not function/system dependant. That entirely depends on the programmer. I have seen 1000-1500 or even more lines of code in a single C file. Keeping twenty functions in a same file makes sense if they are not very different from each other. However if you split the functions among the files, make sure that you write the Makefile properly when compiling them. The phrase " the more split, the easier coding becomes" is debatable.
I liked alk's answer in the closed duplicate: If you follow an object oriented style in C, i.e. use structures and operations on them, the files separate quite naturally in the same way as they would in C++. Operations on the same data types, together forming a "poor man's class", go together.
I'm writing a very small, project-specific OpenGLES engine for iphone and I really need to use a good, solid, and proven dynamic array library/macro in c99 dialect. (No C++, Obj-C, stl whatsoever)
It's strongly necessary for render batch and polygon mesh, so it should be able to handle various types of data, and additionally causes minimal overhead when array size changes and new data is inserted.
I've been searching around and found two candidates for my need.
the first one is from ccCArray from Cocos2d.
and another one is utarray written by Troy D. Hanson.
ccCArray IS rock solid, thoroughly proven by community. utarray looks fine but I cannot find anyone actually uses it.
Any more suggestion?
A library ?! A C++ template would be more than suitable for this need. I'd say about AT MOST 15 functions (excluding alternative constructors and const getters), and you're done. Also able to use it for ANY type, ANY size and ANY size type (byte, int etc.) And it's just one file: a .h or, better said, a .hpp
Any reason you're rejecting it ? Seems like you want to make life harder for yourself :)