Author Topic: GCC global variables  (Read 10056 times)

0 Members and 1 Guest are viewing this topic.

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: GCC global variables
« Reply #50 on: August 04, 2019, 03:10:32 pm »
Volatile means that everyemor load and store in the C "virtual machine" will actually happen and preserve order.
Only wrt. other volatile accesses. The compiler is free to reorder non-volatile accesses around volatile accesses as it sees fit.

Quote
In practice, all C compliers guarantee that variables of certian types will be loaded and stored with a single instruction based on the target ISA.  On a single core CPU that is sufficient to make them atomic, including interrupt context.  This also works for signals if your platform supports them.  So as long as you know what sizes your platform supports you can share volatile variables between main thread and interrupt context.
Only individual reads and writes though. The proposal that deprecates many uses of volatile in C++20 is worth reading.

Edit: The final version of the paper is here, but it doesn't include the rationale discussion.
« Last Edit: August 04, 2019, 03:13:51 pm by andersm »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: GCC global variables
« Reply #51 on: August 04, 2019, 03:10:45 pm »
<snip>
But basically, accessing a variable only within a single source file makes things much clearer, hides the internals of a given module, avoids a lot of possible bugs (the possibility of modifying a variable all over the place can get very nasty for maintenance, and a source of potentially horrible bugs), makes modifications of said module much easier to do, makes you code in a much more structured and modular way (which improves many things including reusability), etc.

I've noticed many people still have a very hard time thinking "modular" when programming, which is unfortunate, and only force themselves doing so (but not necessarily that well) using specific languages. You can write very decent modular code in C. Just because it doesn't include fancy OOP features doesn't mean you should write piles of spaghetti with it.

Getters and setters is a really nice idea but may incur a time penalty for the function calls.  In an interrupt routine (probably calling the 'setter'), the delay may be objectionable.  Of course there is also a delay for the 'getter' call.  Whether it matters depends on the application.  Or, we can declare the functions as 'inline' and eliminate the overhead of the function call.  This look appealing!  We get the benefit of using getters and setters with no overhead for function call/return.

Getters and setters don't solve the issue of needing to enable and disable interrupts around a critical region.  That would still need to be handled somewhere.  The call from inside the interrupt routine has no issues, it is every other call, wherever they are scattered, that have the problem.

So, let the interrupt routine handle the variable directly with no protection and then build the protection into both the getter and the setter functions.  Pretty much guaranteed to work because the interrupt routine can't be called in the middle of getting or setting.

I have never used the functions but I really like the idea.  It kind of depends on how many places in the code manipulate the shared variable.  If it's just once in a mainline, well, there isn't much point in getting carried away.  But if the getter is called all over the code, sure, putting the protection code inside a getter function is a great idea.

In the case of these variables shared with an interrupt routine, I might put the getter and setter code inside the file for the interrupt handler.  That seems like a logical place to put it and makes the intent quite clear.
« Last Edit: August 04, 2019, 03:19:34 pm by rstofer »
 

Offline djacobow

  • Super Contributor
  • ***
  • Posts: 1151
  • Country: us
  • takin' it apart since the 70's
Re: GCC global variables
« Reply #52 on: August 04, 2019, 03:58:57 pm »
"getters" and "setters" can be very cheap, potentially free,  if you have inlining turned on. Even across unit files, they can "disappear" from the intermediate assembly if you are using link-time optimization (which you should -- it's great!)
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: GCC global variables
« Reply #53 on: August 04, 2019, 05:37:04 pm »
"getters" and "setters" can be very cheap, potentially free,  if you have inlining turned on. Even across unit files, they can "disappear" from the intermediate assembly if you are using link-time optimization (which you should -- it's great!)

More important to me is the fact that all references to the shared variable are contained in a single file.  It doesn't matter how code outside the file calls the getter and setter, everything about the variable is contained in a single file.  The variable isn't even known outside the file.  The .h file will contain the prototypes for the functions and that's all that needs to be known to the outside.
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6778
  • Country: pl
Re: GCC global variables
« Reply #54 on: August 04, 2019, 08:09:30 pm »
Global setters/getters are last decade, the fancy way today is dependency injection.
Code: [Select]
#include "my_time_object.h"
#include "irq_driven_time_counter.h"
#include "something_that_needs_to_know_time.h"
int main() {
  my_time_object *time = make_my_time_object();
  irq_driven_time_counter *idtc = make_irq_driven_time_counter(time);
  something_that_needs_to_know_time *blah = make_something_that_needs_to_know_time(time);
  ...
}
That way both irq_driven_time_counter and something_that_needs_to_know_time only need to know how to operate a my_time_object and they don't care about how the program's global time variable is created or where to look for it. They just get a pointer (or reference in other languages) during initialization and remember it internally for their own use.

As for profile guided optimization, it's not something that C has caught up with advanced Java VMs in recent years, it probably predates Java as a language itself. It just doesn't see much use because it's cumbersome - a test run of the program needs to be performed using realistic example data and then everything is recompiled again.

Link time optimization is implemented by adding the compiler's internal code representation to the .o file so that optimizations can be continued as if nothing happened when several .o files are combined. This only works if all .o files are generated with the same compiler and linked using the same compiler's linker, which understands that compiler's internal representation. If a different linker is used or some of the .o files are missing the internal representation, normal machine code from the .o files is copied into the output without optimization.

Somebody mentioned using built-in atomics. These are nice things but should be used with care and understanding of how they are implemented. For example, a normal compiler for x86 userspace applications will not generate code for disabling/reenabling interrupts around an atomic access. In fact, even GCC as configured for Linux kernel compilation won't do that. So better make sure to know what your compiler means by "atomic" before using it ;)
« Last Edit: August 04, 2019, 08:36:55 pm by magic »
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: GCC global variables
« Reply #55 on: August 04, 2019, 09:15:18 pm »
"getters" and "setters" can be very cheap, potentially free,  if you have inlining turned on. Even across unit files, they can "disappear" from the intermediate assembly if you are using link-time optimization (which you should -- it's great!)

More important to me is the fact that all references to the shared variable are contained in a single file.  It doesn't matter how code outside the file calls the getter and setter, everything about the variable is contained in a single file.  The variable isn't even known outside the file.  The .h file will contain the prototypes for the functions and that's all that needs to be known to the outside.
The downside is that if you have many settings that you'll have many getters & setters. Recently I wrote firmware for a realtime system controller with a SCPI command interface. The core of this firmware has 3 layers: the SCPI processor, a generic process and a realtime interrupt driven control process. Each module has an API. Between the SCPI command interface and the generic process I made universal getter and setter functions which take an argument number (from an enumeration) to tell which variable to pass. Between the generic process and the interrupt driven process I made setters which block the interrupt during variable update. However for the getter I made a function which copies the dataset for the interrupt process so the generic process can read whatever it needs. It is just more efficient from a coding point of view.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19493
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: GCC global variables
« Reply #56 on: August 04, 2019, 09:47:38 pm »
Global setters/getters are last decade, the fancy way today is dependency injection.
...
That way both irq_driven_time_counter and something_that_needs_to_know_time only need to know how to operate a my_time_object and they don't care about how the program's global time variable is created or where to look for it. They just get a pointer (or reference in other languages) during initialization and remember it internally for their own use.

That's a fancy new name for something that most of us have been doing for many decades!

Quote
As for profile guided optimization, it's not something that C has caught up with advanced Java VMs in recent years, it probably predates Java as a language itself. It just doesn't see much use because it's cumbersome - a test run of the program needs to be performed using realistic example data and then everything is recompiled again.

Link time optimization is implemented by adding the compiler's internal code representation to the .o file so that optimizations can be continued as if nothing happened when several .o files are combined. This only works if all .o files are generated with the same compiler and linked using the same compiler's linker, which understands that compiler's internal representation. If a different linker is used or some of the .o files are missing the internal representation, normal machine code from the .o files is copied into the output without optimization.

HP's Dynamo project and compiler (c1999) was rather important w.r.t. profile driven optimisation of C.

Practicality is very important. In Java the HotSpot optimisations are automatic and most developers don't even realise they are there and what is happening.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: GCC global variables
« Reply #57 on: August 04, 2019, 11:26:04 pm »
If I were doing this in C, it might look like the following

Timer.h

Code: [Select]
void inline SetTimer(int);
int   inline GetTimer(void);
void InterruptHandler(void);

Timer.c

Code: [Select]
#include “timer.h”

int TimerValue;  // we can't use static int with inline functions or the compiler whines

void inline SetTimer(int NewValue)
{
    /* disable interrupts */
    Timervalue = NewValue;
    /* enable interrupts */
}

int inline GetTimer(void)
{
    /* disable interrupts */
    int Temp = TimerValue;
    /* enable interrupts */
    return Temp;
}

void InterruptHandler(void)
{
    TimerValue++;
}

main.c

Code: [Select]
#include "timer.h"

void main(void)
{
    int TimeNow = GetTimer();
    SetTimer(TimeNow + 10);
}

We have a 3 way choice to make:  If the functions are inline, the variable TimerValue should not be static because GCC whines and snivels.  We can ignore the warnings and try both a static value and inline functions.  Or we can choose inline or static but not both.

It really depends on how often the functions are called.  If the overhead isn't a big deal, remove inline and use a static variable.  This limits the scope to the timer.c file.  If overhead is a big deal, omit static and use inline.  Or try with both - it's just a warning, the computer didn't melt down.


« Last Edit: August 05, 2019, 03:18:16 am by rstofer »
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6778
  • Country: pl
Re: GCC global variables
« Reply #58 on: August 05, 2019, 04:14:39 am »
That's a fancy new name for something that most of us have been doing for many decades!
Quite possibly, software is a retarded field full of young kids who keep reinventing the wheel and cargo culting.
Also, [most of whom] :P Plenty of software in the wild is a tangle of global objects and hidden dependencies.

HP's Dynamo project and compiler (c1999) was rather important w.r.t. profile driven optimisation of C.
Well, back then I admittedly only knew pascal ;)

But it took me two minutes to find this article, written in 1998, about something Intel developed based on their experience from 1992, so presumably somewhere during early to mid nineties.

http://www.drdobbs.com/profile-guided-optimizations/184410561

If nothing else, it clearly proves that the name "PGO" already existed in 1998. I'm pretty sure the idea is even older. Automatic instrumented profiling itself dates back to the early 80s, apparently.

Quote
Dynamic optimization refers to the runtime optimization of a native program binary. This paper describes the design and implementation of Dynamo, a prototype dynamic optimizer that is capable of optimizing a native program binary at runtime... Contrary to intuition, we demonstrate that it is possible to use a piece of software to improve the performance of a native, statically optimized program binary, while it is executing. Dynamo not only speeds up real application programs, its performance improvement is often quite significant. For example, the performance of many +O2 optimized SPECint95 binaries running under Dynamo is comparable to the performance of their +O4 optimized version running without Dynamo.
Wait, what? That's clearly a very different beast than what is normally known as PGO in C/Fortran/etc.
« Last Edit: August 05, 2019, 04:19:12 am by magic »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: GCC global variables
« Reply #59 on: August 05, 2019, 06:32:35 am »
But if i have a getter that returns the value would that need interrups disabling ? if so how does that work as the re-enable interups must come after the value is returned but return is alwas the last line of code in a function?
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: GCC global variables
« Reply #60 on: August 05, 2019, 06:55:26 am »
But if i have a getter that returns the value would that need interrups disabling ? if so how does that work as the re-enable interups must come after the value is returned but return is alwas the last line of code in a function?

You re-enable them before returning from the getter. The point of disabling interrupts is to make sure the value doesn't change DURING the fetch. Once you have a copy of it, you're good in most cases.

Alternately, you move the interrupt control out of the getter/setter routines and do it around the call. This lets you decide if you want to do something critical with the value before re-enabling interrupts.

If the functions are inline and the compiler honors the request, there isn't even going to be a call or a return. The body of the function will replace the function call by the compiler.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: GCC global variables
« Reply #61 on: August 05, 2019, 07:03:18 am »
Oh, so I use a temporary variable in the function and copy the value into it and then return it. Yea, 32 bit CPU sounds much more efficient ;)
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6255
  • Country: fi
    • My home page and email address
Re: GCC global variables
« Reply #62 on: August 05, 2019, 07:06:48 am »
I just noticed that nobody asserted this yet -- we are talking about microcontroller programming using GCC in a semi-freestanding environment, right?
(As opposed to application programming in a hosted environment, or library programming?  Because if we are, I must severely modify my suggestions.)
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: GCC global variables
« Reply #63 on: August 05, 2019, 07:07:47 am »
Oh, so I use a temporary variable in the function and copy the value into it and then return it. Yea, 32 bit CPU sounds much more efficient ;)

Right. And if the function is in-lined, the compiler optimizes that down to a simple assignment to your result variable.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6255
  • Country: fi
    • My home page and email address
Re: GCC global variables
« Reply #64 on: August 05, 2019, 07:15:53 am »
With respect to atomic accesses, many hardware architectures can access memory atomically without disabling interrupts.  This means that enabling/disabling interrupts may not be necessary, or even useful.  GCC __atomic/__sync built-ins should implement those on all hardware architectures.

When disabling and enabling interrupts is useful, it is important to allow nesting, as otherwise you will have to leave it to the caller to manage the interrupts, and document the expectations for every function, every use case, separately.

Nesting simply means that you need as many enables as you have disables to actually re-enable the interrupts.  This is trivial to implement, although it is usually implemented in assembly to ensure the correctness.  (In particular, you do not want to have time-of-check-to-time-of-use bugs, and you want the corner cases to be such that interrupts may be hardware-disabled more than once, but never enabled unless certain.)
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: GCC global variables
« Reply #65 on: August 05, 2019, 08:30:58 am »
One other advantage of get/set functions is the ability to insert range checks and the option to easily create mocks for testing.
You also only have one copy of the platform dependent accessibility code inside this function instead of everywhere the variable is referenced.

Plus you can't pull a pointer of the thing anymore, so that's one more human error that will not occur on this variable anymore.
« Last Edit: August 05, 2019, 01:57:46 pm by Jeroen3 »
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: GCC global variables
« Reply #66 on: August 05, 2019, 01:18:56 pm »
Getters and setters is a really nice idea but may incur a time penalty for the function calls.  In an interrupt routine (probably calling the 'setter'), the delay may be objectionable.

Yes, but I think you didn't quite get my point/approach. I'm not advocating putting a bunch of globals in ONE file with getters and setters for everyone else as someone else suggested. I would actually find this almost as spaghetti-like as the direct externing of globals... I'm saying to make things truly modular.

What it means here is that typically, I would declare (as static volatile) the variable in question in the same source file where the ISR lies, and every other function that has to have fast and direct access to the variable.
No time penalty. Try and make all time-critical functions related to this within the same scope, while keeping a modular logic. In the OP's case, a "timer" module handling all tasks related to the timer for instance: ISR, resetting the counter, and anything else around it (possibly functions that convert the counter to a scaled time value if needed, etc.)

Getters and setters is a really nice idea but may incur a time penalty for the function calls.  In an interrupt routine (probably calling the 'setter'), the delay may be objectionable.
Of course there is also a delay for the 'getter' call.  Whether it matters depends on the application.

Getters or special setters (like a counter reset) would be for the "outside" world and less time-critical uses. So as said above, try and think of all the time-critical uses and keep that inside one module.

For instance, for a timer counter like in the simple OP's example. Some overhead in the getter is no problem here as long as you can guarantee that the getter's overhead is less than the period between two interrupt calls. Which will be very often the case. In many cases, if a getter's overhead is unacceptable, that usually means that the logical and maybe only option would be to perform the given task that reads the variable inside of the ISR anyway...

Of course as I said, you don't have to stubbornly follow this way of doing things in particular cases where directly accessing the variable would still be the only option. There may be cases obviously where this modularity makes things awkward. Common sense always helps.

Or, we can declare the functions as 'inline' and eliminate the overhead of the function call.  This look appealing!  We get the benefit of using getters and setters with no overhead for function call/return.

Yes, you can do that.

I think it has been mentioned earlier in the thread (didn't read it all again), some have suggested that inlining may occur even without declaring functions as "inline". If in separate source files, I wouldn't count on that in the general case. I think this would lie in the "LTO" category (link-time optimizations), and depending on the compiler, that may or may not be available, may or may not handle inlining by itself, and may or may not require a special extra compiler option to be enabled.
« Last Edit: August 05, 2019, 01:26:16 pm by SiliconWizard »
 
The following users thanked this post: Siwastaja

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: GCC global variables
« Reply #67 on: August 05, 2019, 01:22:30 pm »
:clap:One other advantage of get/set functions is the ability to insert range checks and the option to easily create mocks for testing.
You also only have one copy of the platform dependent accessibility code inside this function instead of everywhere the variable is referenced.

Plus you can't pull a pointer of the thing anymore, so that's one more human error that will not occur on this variable anymore.

Yes, as I said earlier, it has many additional benefits. You can add range checks. Much easier to maintain. You can add guarding sections (for interrupted/multi-threaded code). You can convert some values on the fly. You can keep track of every time a "variable" is "read" (could be useful for debugging purposes). You can completely avoid the possibility of a variable being unintentionally modified outside of where it's supposed to be. The list is really almost endless. ;)
 

Offline tombi

  • Regular Contributor
  • *
  • Posts: 163
  • Country: au
Re: GCC global variables
« Reply #68 on: August 05, 2019, 01:42:37 pm »
One issue with globals is initialisation order. It is fine if all your code runs after all the initialisation is complete and if all variables don't depend on any other variable. But if you start adding globals in more than one module and you just want variable x to start with the value that variable y in this other module has... anyway. It can quickly degrade.

Another way of doing this is to use a singleton pattern so instead you export one function that returns a pointer to a structure containing values you want to share. The first time it is called you initialize the structure containing the shared values and return it. After that the function to get the singleton value just passes back the initialized set of values. Of course you have to be careful to make it reentrant and thread safe (if you are doing threads) not to mention making sure the way you use the values is reentrant and thread safe. I'd use this for stuff like global configuration that has to be shared.

Or better still don't use globals and be very careful about what gets shared outside of a module (basically keep the module's business private to the module) and provide access to these few things you have to provide access to by getter/setter. (What Silicon Wizard said).

Ok this is pretty general advice - hope it helps....

Tom
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: GCC global variables
« Reply #69 on: August 05, 2019, 01:50:04 pm »
One issue with globals is initialisation order. It is fine if all your code runs after all the initialisation is complete and if all variables don't depend on any other variable. But if you start adding globals in more than one module and you just want variable x to start with the value that variable y in this other module has... anyway. It can quickly degrade.

Yeah. But you should really avoid any kind of such cross-dependencies when you can. It's nasty anyway.
Design-wise, such dependency should NOT be seen as a dependency between globals anyway IMO, but a dependency between said modules. That's not really a variable problem per se. It's all about module initialization. Some modules may be required to be ready before some others: just add whatever means is practical to handle this.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19493
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: GCC global variables
« Reply #70 on: August 05, 2019, 02:04:13 pm »
:clap:One other advantage of get/set functions is the ability to insert range checks and the option to easily create mocks for testing.
You also only have one copy of the platform dependent accessibility code inside this function instead of everywhere the variable is referenced.

Plus you can't pull a pointer of the thing anymore, so that's one more human error that will not occur on this variable anymore.

Yes, as I said earlier, it has many additional benefits. You can add range checks. Much easier to maintain. You can add guarding sections (for interrupted/multi-threaded code). You can convert some values on the fly. You can keep track of every time a "variable" is "read" (could be useful for debugging purposes). You can completely avoid the possibility of a variable being unintentionally modified outside of where it's supposed to be.

Unless some miscreant has managed to create a pointer to it. The mere possibilty of such aliasing prevents many optimisations.

Yes, you can tell the compiler "no aliasing occurs", but then what about debuggers, and will the noalias continue to be valid after 3 years of maintenance?

Quote
The list is really almost endless. ;)

Getters and setters are A Good Thing.

Even better is to not have exposed state.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: GCC global variables
« Reply #71 on: August 05, 2019, 02:20:39 pm »
Unless some miscreant has managed to create a pointer to it. The mere possibilty of such aliasing prevents many optimisations.

Indeed. But accessing such a variable through a pointer would pretty much defeat all benefits of the above approach. Mixing both ways of accessing a variable is a recipe for disasters, readability and maintenance issues.

That said, you're right about compiler optimization: usually the default is they consider that aliasing may occur. I think the "restrict" qualifier in C99+ helps with that. I've only used it very sparingly though, and AFAIR, never in any "embedded" code. (Did it to optimize intensive FP routines meant for PC hosts. The result, with additional alignment attributes, was dramatically better ;D )
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: GCC global variables
« Reply #72 on: August 05, 2019, 08:59:16 pm »
One other advantage of get/set functions is the ability to insert range checks and the option to easily create mocks for testing.
You also only have one copy of the platform dependent accessibility code inside this function instead of everywhere the variable is referenced.
I'd like to emphasize the range checking. I always add these to external interfaces of modules. If a program goes haywire and starts to execute your program randomly (I've seen this happen!) then the range check will prevent damage and contain the situation. In some of my firmware I have 2 or even more range checks between the input value and the result which is used to control hardware.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: GCC global variables
« Reply #73 on: August 05, 2019, 09:49:42 pm »
Yep. I actually do parameters checking in almost ALL my functions actually, not just at the interface level (except a very few that either wouldn't benefit from it or are extremely time-critical, in which case I try and make sure that parameters/variables they use will be in the right ranges in upper levels) and have been doing so for years now. That's what is sometimes called "defensive" programming, or something in that vein. I've never regretted doing that. Of course that incurs having to deal with a fair amount of error checking, which I happen not to mind either. I personally wouldn't do it any other way. The small overhead is well worth it IME. Of course, some other people don't like to do this and even expose a large list of arguments why. That's fine. I'm no evangelist. ;D
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: GCC global variables
« Reply #74 on: August 05, 2019, 10:29:10 pm »
Yep. I actually do parameters checking in almost ALL my functions actually, not just at the interface level .... That's fine. I'm no evangelist. ;D

Watch out, some youngster will re-invent this idea and call it "the explicit contract verification paradigm" and it will take off.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf