January 27, 2022
On Wednesday, 26 January 2022 at 23:40:48 UTC, H. S. Teoh wrote:
>
> After many experiences of this, I've come to the conclusion that the convenience of using globals is usually not worth the trouble they cause down the road. I rather "waste" a bit more time writing things the "right" way now, than to waste a LOT of time (and frustration) later trying to debug code riddled with global state.
>
>
> T

I just counted the globals in my GUI IDE (that I developed with C#/Winforms.

34

many set deafault, that can later be modified during function calls, depending on needs at the time.

Without globals, I'd never have bothered ;-)

bool new_compile_needed = true;
public bool new_record_mode = false;
static string custom_tmp = System.IO.Path.GetTempPath() + @"EZ_Compiler\";
string vcvar64 = "";
string vcvar32 = "";
string clang_exe = "clang.exe";
bool Is64Bit;
string clang_xp = @"C:\LLVM\bin\clang-cl.exe";
static string g_cl_c_options = @" /nologo /W4 /GS- /Od";
string g_cl_c_options_new = g_cl_c_options;
static string g_cl_cpp_options = @" /nologo /EHsc /W4 /GS- /Od";
string g_cl_cpp_options_new = g_cl_cpp_options;
static string langversion = @" /langversion:default";
static string g_csc_options = @" /nologo /warn:4 /warnaserror+ /nowarn:168,164 /checked+" + langversion + " /optimize+ /target:exe";
string g_csc_options_new = g_csc_options; // see compile method...
static string g_csc_unsafe_options = @" /nologo /warn:4 /warnaserror+ /nowarn:168,164 /checked+" + langversion + "  /optimize+ /unsafe /target:exe";
string g_csc_unsafe_options_new = g_csc_unsafe_options;
bool vs2019_available = false;
bool vs2015_available = false;
string exeDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string current_file = "Current File: (none)";
string dcompiler_mars = "dmd.exe";
string dcompiler_llvm = "ldc2.exe";
string dcompiler = "dmd.exe";
string gocompiler = "go.exe";
string jscompiler = "jrunscript";
string cs_formatter = @"CodeFormatter.exe";
string csprojFileName = custom_tmp + "cs" + ".csproj";
string myDLibDirectory = @" -i -I="  + '\u0022' + "D:\\My Documents\\Dlib"  + '\u0022' + " ";
string Cpp64dll = @"c:\nowheretobefound";
string Cpp32dll = @"c:\nowheretobefound";
string myDocsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
System.Drawing.Color MyBackColor = Color.Black;
System.Drawing.Color MyForeColor = Color.Lavender;

January 26, 2022
On Thu, Jan 27, 2022 at 12:45:20AM +0000, forkit via Digitalmars-d wrote: [...]
> I just counted the globals in my GUI IDE (that I developed with C#/Winforms.
> 
> 34
> 
> many set deafault, that can later be modified during function calls, depending on needs at the time.
> 
> Without globals, I'd never have bothered ;-)
[...]

Some of your globals are actually global values, like:

> string clang_exe = "clang.exe";
> bool Is64Bit;
> bool vs2019_available = false;
> bool vs2015_available = false;
> string dcompiler_mars = "dmd.exe";
> string dcompiler_llvm = "ldc2.exe";

These I wouldn't be ashamed of declaring as globals, since they ARE globals (in the sense of describing the global environment the program will run in).  You can usually tell these from other globals by whether or not you can make them immutable (though sometimes you may want to keep them mutable if, e.g., you're picking them up from the runtime environment or via program options -- but the idea being that once they're initialized they're effectively immutable).

Others, however, I'd stick into a configuration struct or as member fields in your program's main class, such as:

> bool new_compile_needed = true;
> public bool new_record_mode = false;
> System.Drawing.Color MyBackColor = Color.Black;
> System.Drawing.Color MyForeColor = Color.Lavender;


T

-- 
Do not reason with the unreasonable; you lose by definition.
January 27, 2022
On Thursday, 27 January 2022 at 01:01:56 UTC, H. S. Teoh wrote:
> On Thu, Jan 27, 2022 at 12:45:20AM +0000, forkit via Digitalmars-d wrote: [...]
>> I just counted the globals in my GUI IDE (that I developed with C#/Winforms.
>> 
>> 34
>> 
>> many set deafault, that can later be modified during function calls, depending on needs at the time.
>> 
>> Without globals, I'd never have bothered ;-)
> [...]
>
> Some of your globals are actually global values, like:
>
>> string clang_exe = "clang.exe";
>> bool Is64Bit;
>> bool vs2019_available = false;
>> bool vs2015_available = false;
>> string dcompiler_mars = "dmd.exe";
>> string dcompiler_llvm = "ldc2.exe";
>
> These I wouldn't be ashamed of declaring as globals, since they ARE globals (in the sense of describing the global environment the program will run in).  You can usually tell these from other globals by whether or not you can make them immutable (though sometimes you may want to keep them mutable if, e.g., you're picking them up from the runtime environment or via program options -- but the idea being that once they're initialized they're effectively immutable).
>
> Others, however, I'd stick into a configuration struct or as member fields in your program's main class, such as:
>
>> bool new_compile_needed = true;
>> public bool new_record_mode = false;
>> System.Drawing.Color MyBackColor = Color.Black;
>> System.Drawing.Color MyForeColor = Color.Lavender;
>
>
> T

The distinction is basically between global state (i.e. things that are mutated often, like "pointer to current item") and globals that are *stated* e.g. "Is logging turned on". The latter is mostly fine with the caveat that it can be indicative of bad architecture (e.g. multiple instances of something like an interpreter is often impossible with any global state at all), the former is extremely bad and can absolutely ruin a program. If you have lots of global state (or even local state whose structure isn't natural) you are doing something wrong.
January 27, 2022

On Wednesday, 26 January 2022 at 11:38:51 UTC, forkit wrote:

>

On Wednesday, 26 January 2022 at 11:29:31 UTC, forkit wrote:

>

so you asked for an example where you could slip up using a global variable.

> >

well, that was an example.

> >

you have a local variable the same name as global variable.. you mistyped... and... boom!

>

oh. what is actually going on in foo is irrelevant of course.

foo does nothing of any relevance.

the point I was making, was about having a global variable with the same name as as a local variable, could 'potentially' slip you up.

Thanks for the example! You are right but I personally would never use global variables this way as it doesn't make sense. The idea is that, the global should be shared across every (or most) function in my project so there is no point to create a local variable with the same name (which probably also means that it does the same thing as your global one) as the global one. In this case, it will be better to use a local variable. It also makes a lot more sense.

January 27, 2022

On Wednesday, 26 January 2022 at 11:52:13 UTC, Mark wrote:

>

Some examples of global variables that are frequently used:

  1. C has an implicit global variable in all programs - errno.
  2. If you are writing asm blocks (in C or D), then the processor's flags and registers are obviously global variables that can affect the function's behavior. At least in D the compiler will complain if a function is marked pure but has an inner asm block; the block has to be annotated explicitly with pure.
  3. The language runtime might also be considered as one giant global variable. As an example, a function may return successfully on one invocation and fail on another despite being pure and being invoked with the same parameters, just because a memory allocation has failed. Potentially, you could even catch and handle OurOfMemoryErrors (something which you aren't supposed to do, I think) and change function behavior based on that. However, if I'm not mistaken, any issues related to memory allocation aren't typically considered a part of the function's "contract"; otherwise, pure would only be possible if @nogc is also present.

Thanks for the examples! In '3', you could of course pass "-betterC" so there is no garbage collector at all. Also even if there is no garbage collector, you can have a memory allocation and it can fail. Just wanted to note that.

January 27, 2022

On Wednesday, 26 January 2022 at 14:16:57 UTC, jmh530 wrote:

>

I have the same worries about global mutables as others...

I understand. You must be very careful with them and they should be used only in specific cases.

January 27, 2022

On Wednesday, 26 January 2022 at 14:44:28 UTC, bachmeier wrote:

>

The numbers behind the name are roughly the year of the standard. FORTRAN 66 and FORTRAN 77 used all caps. Fortran 90 and later dropped the all caps thing.

Modern Fortran isn't bad if you're working in the domain for which it was written. I wouldn't hesitate to take it over C, C++, or Rust for that type of work.

That's cool! What was it written for?

January 27, 2022

On Wednesday, 26 January 2022 at 15:10:44 UTC, max haughton wrote:

>

If a class is reasonable, use a class, however if it's just some mutable state then use a struct since you don't need OOP

Yeah, I changed my code to use a struct. I don't need to allocate memory on the heap and I use "betterC" so I cannot use classes anyway. Thanks!

January 27, 2022

On Wednesday, 26 January 2022 at 15:36:52 UTC, H. S. Teoh wrote:

>

Thanks to UFCS, you don't need to define every function that operates on the struct/class as a method. Free functions work just fine.

I.e., instead of this:

struct MyData {
int x;
void method() {
x++;
}
}

MyData data;
data.method();

you could also write this:

struct MyData {
int x;
}

void method(ref MyData mydata) {
mydata.x++;
}

MyData data;
data.method();

T

That's cool! Thanks!

January 27, 2022

On Wednesday, 26 January 2022 at 15:47:06 UTC, Bienlein wrote:

>

I once worked on a system (written in Java) that was a huge commercial success. The company has a revenue of about €100 million from it. What later turned out should always have been passed on to methods as a parameter was always a global function. Now many person years have been spent on development and countless lines have been written and there is absolutely no way to fix this as the effort in time and money is way to large. For some little programs you might get away with some globals, but not in case of lage systems.

Thanks for the example! I must say that I didn't though about big projects that will be shared across a lot of developers. Thankfully, thanks to all these replays, I have learned my lesson!