variable declaration (implicit and explicit and advantages & disadvantages) - variable-declaration

"What are explicit declaration & implicit declaration of variables in programming language concepts and their advantages and disadvantages?"

An explicit declaration is when you start making the variable by order it first.
ex: String name; name="yourname";
the advantages is you be able to fill your variable with any algorithm or math logic to make a value. the disadvantages is when you use it as a material without fill the value of your variable ,there will be an error.
An implicit declaration is when you make a variable directly without order it first. ex : String name="yourname";
the advantages : it is a practically treatment at some condition.
.

Explicit means declaring variable like in c.
Implicit declaration in variable declaration in python.
In Explicit we should cast.
In implicit no need of casting.

Explicit variable declaration means that the type of the variable is declared before or when the variable is set. Implicit variable declaration means the type of the variable is assumed by the operators, but any data can be put in it.
In C,
int x = 5; printf(x-5); x = "test"; printf(x-5);
returns a compile time error when you set x to test
but in Python,
x = 5; print(x-5); x = "test"; print(x-5);
will "compile" (python doesn't compile, but it will run the program) and give you a runt time error when you try to subtract from the string.
One advantage of Implicit variables is that it makes it easier to write code without worrying about the behind the scenes data type, the compiler should pick the appropriate one based on its future usage.
Another advantage is that you can flexibly type a variable to hold different things that may not even share a parent class. Doing this is risky, as you have no guarantees that the objects will be interpreted correctly by following code.
One disadvantage is that Implicit variables have no guarantees of what they are. A function that computes the difference between two numbers will not return an compile time error if the variables have strings in them. You passed in two variables, it is up to you to ensure they are the right type. It also makes reading code harder in some ways. var nextLocation = LeftHandedSmokeShifter(3.3) is completely legitimate code, but You have to look up the function to even guess what it is doing. string nextLocation = LeftHandedSmokeShifter(3.3) at least tells me that I should be using the output for mathematical operations.
Type heavy languages are always explicitly declared and typed, but type weak languages are mostly implicitly typed. If you can set a variable to "Var" it is likely an implicitly typed language.

Related

How are quantities referenced in Fortran?

I was told a long time ago that in FORTRAN, everything is passed by value. Therefore I would need to do this (provided mySubroutine is suitably defined elsewhere):
double precision :: myArray(2)
myArray(1:2) = (/ 2.3d0, 1.5d0 /)
CALL mySubroutine(myArray)
However, I also found that the program compiles and runs as expected if I do this
CALL mySubroutine((/ 2.3d0, 1.5d0 /))
without needing to define an intermediary array myArray. I thought that I was passing myArray into mySubroutine by reference. What is going on under the hood in the second version? Is the compiler unpacking the subroutine call, declaring a temporary variable only to pass it by reference?
To a large extent, trying to classify Fortran procedure calling with pass-by-reference and pass-by-value is not too helpful. You can find more detail on that in response to questions like this one and this one.
In short, generally procedure references are such that changes to a variable in a procedure are reflected in the variable where the procedure was referenced. In some cases a compiler may choose to do copy-in/copy-out, and in others it effectively must. Equally, the value attribute of a dummy argument specifies that an anonymous copy be made.
Where this question adds something a little different is in the use of an expression such as in
call mySubroutine([2.3d0, 1.5d0]) ! Using F2003 array constructor syntax
Is the compiler creating a temporary variable?
Admittedly, this is perhaps just a looseness in terminology but it's worth saying that there is certainly no variable involved. [2.3d0, 1.5d0] is an expression, not a variable. Crucially this means that it cannot be modified (appear in a variable definition context) in the procedure. Restrictions that apply in the case using an expression rather than a (temporary) variable include:
the dummy argument associated with an expression may not have the intent(inout) or the intent(out) attribute;
if the dummy argument hasn't an intent attribute then that argument may not be modified if the associated actual argument is an expression.
Now, if the dummy argument has the value attribute the effect of the procedure is the same whichever way it is referenced.
To conclude, the program may work just as well with an expression instead of an intermediate variable. If it doesn't that's because of violation of some aspect of Fortran. How it works is a problem for the compiler not the programmer.

"Only static constant integral variables may be initialized within a class "

can someone explain to me why cant i initialize a static variable inside the class ? what happens in compilation time exactly ?
for example :
class Object {
static int numberOfObjects = 0; // This gives the error
Object(){
nummberOfObjects++;
}
};
Thanks !
It's just a rule from the standard that was implemented by the compiler. The fact that it was a rule doesn't mean the opposite isn't possible, as the change in the newer C++11 standard and according compilers show.
In versions of C++ prior to C++11, the language standard simply doesn't allow you to perform a static variable definition inside the class declaration. In other words, You can't initialize it because it isn't constant. Since it can change during execution, the compiler needs some memory allocated somewhere to actually keep the value in. Since this is a class declaration, it doesn't actually allocate the memory for you. This issue doesn't exist for const values because they don't need memory assigned -- they are effectively "hard coded" just like if you replaced them with literals (or an old 'C' style #define).
You need a line of code outside of the class declaration that basically says:
int Object::numberOfObjects = 0;
This line isn't just initializing the static class variable, it's actually allocating a static int that will be used to store the value. The line of code up in the class declaration doesn't do this -- it merely tells the compiler that such a value exists somewhere.
Note that starting with C++11 this behavior is different. The language is now smart enough to figure out that you DO want to that memory defined, so you no longer need to do so manually.

Preference on initialising variables in C++

Starting out in c++ and noticed that you could initialise a variable in two ways
int example_var = 3; // with the assignment operator '='
or
int example_var(3); // enclosing the value with parentheses
is there a reason to use one over the other?
The first form dates back from the C time, while the second was added in C++. The reason for the addition is that in some contexts (in particular initializer lists in constructors) the first form is not allowed.
The two are not exactly equivalent for all types, and that is where one or the other might be more useful. The first form semantically implies the creation of a temporary from the right hand side, followed by the copy construction of the variable from that temporary. The second form, is direct initialization of the variable from the argument.
When does it matter?
The first form will fail if there is no implicit conversion from the right hand side to the type of the variable, or if the copy constructor is not available, so in those cases you will have to use direct initialization.
The second form can be used in more contexts than the first, but it is prone to the most-vexing-parse. That is, in some cases the syntax will become compatible with a declaration for a function (rather than the definition of a regular variable), and the language determines that when this is the case, the expression is to be parsed as a function declaration:
std::string s = std::string(); // ok declares a variable
std::string s( std::string() ); // declares a function: std::string s( std::string(*)() )
Finally in C++11 there is a third form, that uses curly braces:
std::string s{std::string{}};
This form has the advantages of direct initialization with parenthesis, but at the same time it is not prone to misinterpretation.
Which one to use?
I would recommend the third option if available. That being said, I tend to use the first more often than not, or the second depending on the context and the types...
For built in types like int both mean the same.
But for custom data types they can mean different. First format is called Copy Initialization while second is called Direct Initialization.
Good Read:
Is there a difference in C++ between copy initialization and direct initialization?
Their output is the same...
the both the syntax call the copy constructor.
It is same for int and other similar built in data types, though some difference is there for user defined data types.
They compile to the same thing. However, both are a form of variable initialization, not assignment, which matters a little in C and a lot in C++ since totally different functions (constructor v. assignment) are called.

is static const string member variable always initialized before used?

In C++, if I want to define some non-local const string which can be used in different classes, functions, files, the approaches that I know are:
use define directives, e.g.
#define STR_VALUE "some_string_value"
const class member variable, e.g.
class Demo {
public:
static const std::string ConstStrVal;
};
// then in cpp
std::string Demo::ConstStrVal = "some_string_value";
const class member function, e.g.
class Demo{
public:
static const std::string GetValue(){return "some_string_value";}
};
Now what I am not clear is, if we use the 2nd approach, is the variable ConstStrVal always initialized to "some_string_value" before it is actually used by any code in any case? Im concerned about this because of the "static initialization order fiasco". If this issue is valid, why is everybody using the 2nd approach?
Which is the best approach, 2 or 3? I know that #define directives have no respect of scope, most people don't recommend it.
Thanks!
if we use the 2nd approach, is the variable ConstStrVal always initialized to "some_string_value" before it is actually used by any code in any case?
No
It depends on the value it's initialized to, and the order of initialization. ConstStrVal has a global constructor.
Consider adding another global object with a constructor:
static const std::string ConstStrVal2(ConstStrVal);
The order is not defined by the language, and ConstStrVal2's constructor may be called before ConstStrVal has been constructed.
The initialization order can vary for a number of reasons, but it's often specified by your toolchain. Altering the order of linked object files could (for example) change the order of your image's initialization and then the error would surface.
why is everybody using the 2nd approach?
many people use other approaches for very good reasons…
Which is the best approach, 2 or 3?
Number 3. You can also avoid multiple constructions like so:
class Demo {
public:
static const std::string& GetValue() {
// this is constructed exactly once, when the function is first called
static const std::string s("some_string_value");
return s;
}
};
caution: this is approach is still capable of the initialization problem seen in ConstStrVal2(ConstStrVal). however, you have more control over initialization order and it's an easier problem to solve portably when compared to objects with global constructors.
In general, I (and many others) prefer to use functions to return values rather than variables, because functions give greater flexibility for future enhancement. Remember that most of the time spent on a successful software project is maintaining and enhancing the code, not writing it in the first place. It's hard to predict if your constant today might not be a compile time constant tomorrow. Maybe it will be read from a configuration file some day.
So I recommend approach 3 because it does what you want today and leaves more flexibility for the future.
Avoid using the preprocessor with C++. Also, why would you have a string in a class, but need it in other classes? I would re-evaluate your class design to allow better encapsulation. If you absolutely need this global string then I would consider adding a globals.h/cpp module and then declare/define string there as:
const char* const kMyErrorMsg = "This is my error message!";
Don't use preprocessor directives in C++, unless you're trying to achieve a holy purpose that can't possibly be achieved any other way.
From the standard (3.6.2):
Objects with static storage duration (3.7.1) shall be zero-initialized
(8.5) before any other initialization takes place. A reference with
static storage duration and an object of POD type with static storage
duration can be initialized with a constant expression (5.19); this is
called constant initialization. Together, zero-initialization and
constant initialization are called static initialization; all other
initialization is dynamic initialization. Static initialization shall
be performed before any dynamic initialization takes place. Dynamic
initialization of an object is either ordered or unordered.
Definitions of explicitly specialized class template static data
members have ordered initialization. Other class template static data
members (i.e., implicitly or explicitly instantiated specializations)
have unordered initialization. Other objects defined in namespace
scope have ordered initialization. Objects defined within a single
translation unit and with ordered initialization shall be initialized
in the order of their definitions in the translation unit. The order
of initialization is unspecified for objects with unordered
initialization and for objects defined in different translation units.
So, the fate of 2 depends on whether your variable is static initialised or dynamic initialised. For instance, in your concrete example, if you use const char * Demo::ConstStrVal = "some_string_value"; (better yet const char Demo::ConstStrVal[] if the value will stay constant in the program) you can be sure that it will be initialised no matter what. With a std::string, you can't be sure since it's not a POD type (I'm not dead sure on this one, but fairly sure).
3rd method allows you to be sure and the method in Justin's answer makes sure that there are no unnecessary constructions. Though keep in mind that the static method has a hidden overhead of checking whether or not the variable is already initialised on every call. If you're returning a simple constant, just returning your value is definitely faster since the function will probably be inlined.
All of that said, try to write your programs so as not to rely on static initialisation. Static variables are best regarded as a convenience, they aren't convenient any more when you have to juggle their initialisation orders.

Location of const in a function

A similar question was previously asked, but none of the answers really provided what I was looking for.
I am having trouble deciding where consts should be located in a function. I know a lot of people put them at the top, but if you put them as close as possible to where they are used, you'll reduce code span. I.e.
void f() {
const FOO = 3;
...// some code
if ( bar > FOO ) {
...// do stuff
}
}
or
void f() {
...// some code
const FOO = 3;
if ( bar > FOO ) {
...// do stuff
}
}
I'm leaning towards using the const at the top in small functions, and keeping the span as close as possible in large functions, but I was wondering what others' styles/thoughts are regarding this.
At the lowest scope possible, and directly before their first use.
As a matter of style, exceptions can be made for clarity/asthetics, e.g., grouping conceptually similar constants.
Many times, const values are placed at the top of the file so that they are easily recognizable (and "findable") to individuals doing development. However, if you only need a const value for a very small piece of code, it would be better for it to be scoped to only where it is needed as you suggested.
I recommend putting them in the header file under a namespace or class.
Your approach sounds about right.
I even put these magic numbers at the top of a file sometime, to make sure any "settings" or tweakables are highly visible to others.
It depends on what you really want to do. I usually put them very close where they are actually used.
I put them on top when they are grouped and in order to make sense of one you have to look at the others (for instance when a constant depends on another constant).
Especially if you are going to code some longer algorithm having all start values (including const values) and variables declared at the top of the function makes for a lot more clarity when reading the algorithm itself.
In pre-C99 versions of C, you could only define variables at the beginning of blocks. Consequently, the second alternative was not valid C code. I believe that Code Complete favors putting the declaration as close as possible to the first use, but some would have argued against that rule on the grounds making it makes things inconsistent between C and C++.
Now that both standard C and C++ allow you to move the declaration close to the first usage, that objection no longer holds.
There are times when there are compelling reasons why putting the declaration as late as possible is better for non-const variables than at the top. For example, a declaration without an initialization opens up the possibility of accidentally reading an uninitialized variable. Furthermore, in C++, declaring a class variable at the top of the function with no initialization invokes the default constructor. When it's later assigned, it invokes the assignment operator. If the variable were instead declared at the point of initialization, that invokes the copy constructor. The cost of a default constructor + assignment can often be larger than the cost of the copy constructor.
This last argument can only apply to non-const variables, obviously, since there is no assignment on a const variable. But, why would you want to have to look in a different place for your const declarations? And if const int n=3; is obviously const, what about const char *s = "FOO";? Is that const enough to belong at top or not? Or does it have to be const char * const s = "FOO";? Also, what if you don't yet know what value you want your const variable initialized to at the top, then you must postpone declaring your const variable until you know what it needs to be initialized to.