Since I found this particular documentation on https://www.tutorialspoint.com/c_standard_library/c_function_rand.htm,I have been thinking about this particular line of code srand((unsigned)time(&t));.Whenever I had to generate some stuff,I used srand(time(NULL)) in order not to generate the same stuff everytime I run the program,but when I came across this,I have been wondering :Is there any difference between srand((unsigned)time(&t)) and srand(time(NULL))?Because to me they seem like they do the same thing.Why is a time_t variable used?And why is the adress operator used in srand()?
#include <stdio.h>
#include<stdlib.h>
int main(){
int i,n;
time_t t;
n = 5;
srand((unsigned)time(&t));
for (i = 0; i < n; i++) {
printf("%d\n", rand() % 50);
}
return(0);
}
Yes, it will yield the same result. But the example is badly written.
I would be careful reading Tutorialspoint. It's a site known for bad C code, and many bad habits you see in questions here at SO can be traced to that site. Ok, it's anecdotal evidence, but I did ask a user here why they cast the result of malloc, and they responded that they had learned that on Tutorialspoint. You can actually see (at least) four examples in this short snippet.
They cast the result from the call to time() which is completely unnecessary and just clutters the code.
For some reason they use the variable t, which is completely useless in this example. If you read the documentation for time() you'll see that just passing NULL is perfectly adequate in this example.
Why use the variable n? For this short example it's perfectly ok with a hardcoded value. And when you use variables to avoid hardcoded values, you should declare them const and give them a much more descriptive name than n. (Ok, I realize I was a bit on the edge when writing this. Omitting const isn't that big of a deal, even if it's preferable. And "n" is a common name meaning "number of iterations". And using a variable instead of a hard coded value is in general a good thing. )
Omitted #include<time.h> which would be ok if they also omitted the rest of the includes.
Using int main() instead of int main(void).
For 5, I'd say that in most cases, this does not matter for the main function, but declaring other functions as for example int foo() with empty parenthesis instead of int foo(void) could cause problems, because they mean different things. From the C standard:
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.
Here is a question related to that: What are the semantics of function pointers with empty parentheses in each C standard?
One could also argue about a few other things, but some people would disagree about these.
Why declare i outside the for loop? Declaring it inside have been legal since C99, which is 20 years old.
Why end the function with return 0? Omitting this is also ok since C99. You only need to have a return in main if you want to return something else than 0. Personally, in general I find "it's good practice" as a complete nonsense statement unless there are some good arguments to why it should be good practice.
These are good to remember if your goal is to maintain very old C code in environments where you don't have compilers that supports C99. But how common is that?
So if I got to rewrite the example at tutorialspoint, i'd write it like this:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
srand(time(NULL));
for (int i = 0; i < 5; i++) {
printf("%d\n", rand() % 50);
}
}
Another horrible example can be found here: https://www.tutorialspoint.com/c_standard_library/c_function_gets.htm
The function gets is removed from standard C, because it's very dangerous. Yet, the site does not even mention that.
Also, they teach you to cast the result of malloc https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm which is completely unnecessary. Read why here: Do I cast the result of malloc?
And although they mention that malloc returns NULL on failure, they don't show in the examples how to properly error check it. Same goes for functions like scanf.
Related
I saw the link http://www.cs.uregina.ca/Links/class-info/cplusplus/Standards/Disk10/aliasing_c.html about aliasing in c. The program there is shown below.
/********************************
An example of aliasing in C.
Output:
3
3
********************************/
#include < stdio.h >
int main()
{
int G_Var = 2;
/* call SomeFunction with the Global Variable as a parameter */
SomeFunction(G_Var);
return 0;
}
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
{
int G_Var;
int InputVar;
/* Global Variable is set to new value */
G_Var = InputVar + 1;
/* Equivalent to G_Var = G_Var + 1 */
printf("%i\n", InputVar);
printf("%i\n", G_Var);
}
Is the code correct and is working according to what is commented in the code?
Whoever wrote the link was severely incompetent and shouldn't be teaching C. They should rather enlist in a beginner's class themselves.
int G_Var = 2; is not a global variable, it is a local one with automatic storage duration. Both the one in main() and the one inside the function.
The code posted is C++, not C. C does not have references.
The term alias/aliasing refers to when several pointers (or C++ references) may be assumed to point at the same memory location.
int InputVar; in the function conflicts with the parameter name so the code doesn't make any sense. In case there were no name conflict, the variable would be uninitialized and then used, which would be senseless.
Is the code correct and is working according to what is commented in the code?
Whoever wrote this example was so confused that it's really hard to be telling what they are trying to teach, or in which language for that matter. The code does not compile for multiple fundamental reasons. Just forget about this mess.
Four things to say:
C does not have C++-kind of aliases/references. It is a C++ feature only.
So,
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
is wrong.
G_Var is not a global variable. You declare it two times to be local to main and SomeFunction. If you want to declare G_Var as global variable it has to be declared once at global scope, not inside of a function, and only access it by its name, not declaring its type twice.
But beside that the use of global variables is deprecated. Rather use parameter passing.
SomeFunction() isn't declared before the call to it in main(). Usually this would give you a diagnostic as the compiler don't know what SomeFunction() is.
InputVar is used as reference parameter, but also declared twice in SomeFunction. Here is a conflict.
I guess you never compiled this code before asking, which is a fault. It would have answered many questions of yours including the main one.
"Is the illustration on Aliasing in C correct?"
"Is the code correct and is working according to what is commented in the code?"
No, it isn't. The whole code is defective.
It gives the impression that the authors didn't knew how to either write correct C nor C++ code.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm learning C and programming in general, and I don't know when to return a value and when to use void.
Is there any rule to apply when to use one over the another ?
Is there any difference between this two cases? I know that first case is
working with a local copy of int (n) , and second with original value.
#include <stdio.h>
int case_one(int n)
{
return n + 2;
}
void case_two(int *n)
{
*n = *n + 2;
}
int main(int argc, char *argv[])
{
int n = 5;
n = case_one(n);
printf("%i\n", n);
n = 5;
case_two(&n);
printf("%i\n", n);
return 0;
}
There is one more reason to use out param instead of return value - error handling. Usually return value (int) of the function call in C represents success of the operation. Error represented by not 0 value.
Example:
#include <stdio.h>
int extract_ip(const char *str, int out[4]) {
return -1;
}
int main() {
int out[4];
int rv = extract_ip("test", out);
if (rv != 0) {
printf("Error :%d", rv);
};
}
This approach used in POSIX socket API for example.
It very much depends on what you want to do, but basically You should use the former unless You have a good reason to use the latter.
Think of the implications of the choices. First, let's think about the way we provide input to function. It is quite often that you provide explicitly constant, compile-time constant or temporary data as input:
foo(1);
const int a = 2;
foo(a);
int x = 5;
int y = 5;
foo(x + y);
In all of the above cases the source of initial value is not a viable location for storing the result.
Next, let's think about how we may want to store the result. Foremost we may often want to use the result elsewhere. It may be inconvenient to use the same variable to store and then pass input, and to store output. But furthermore, often we would like to use the result immediately. We invoke the function as a part of larger expression:
x = foo(1) + foo(2);
Rewriting the preceding line in a manner that would use a pointer would require much unnecessary code - that is time and complication that we certainly don't want, when it's not really buying anything.
So when do we actually want to use a pointer? C functions are pass-by-value. Whenever we pass anything, a copy is created. We can then work on that copy and upon returning it, it requires copying again. If we do know that all we want to do is manipulate certain data set in place, we can provide a pointer as a handler and all that is copied is several bytes that store address.
So the former, prevalent way to create functions is flexible and leads to concise usage. The latter is useful for manipulation of objects in place.
Obviously sometimes our input actually is an address, and that's a trivial case for using pointers as function parameters.
I'm learning C and programming in general, and i don't know when to return a value and when to use void.
There is no definitive rule, and it is a matter of opinion. Notice that you might re-code your case_one as the following:
// we take the convention that the first argument would be ...
// a pointer to the "result"
void case_one_proc(int *pres, int n) {
*pres = n+2;
}
then a code like
int i = j+3; /// could be any arbitrary expression initializing i
int r = case_one(i);
is equivalent to
int i = j+3; // the same expression initializing i
int r;
case_one_proc(&r, i); //we pass the address of the "result" as first argument
Hence, you can guess that you might replace any whole C program with an equivalent program having only void returning functions (that is, only procedures). Of course, you may have to introduce supplementary variables like r above.
So you see that you might even avoid any value returning function. However, that would not be convenient (for human developers to code and to read other code) and might not be efficient.
(actually you could even make a complex C program which transforms the text of any C program -given by their several translation units- into another equivalent C program without any value returning function)
Notice that at the most elementary machine code level (at least on real processors like x86 and ARM), everything are instructions, and expressions don't exist anymore! And you favorite C compiler is transforming your program (and every C program in practice) into such machine code.
If you want more theory about such whole-program transformations, read about A-normal forms and about continuations (and CPS transformations)
Is there any rule to apply when to use one over the another ?
The rule is to be pragmatic, and favor first the readability and understandability of your source code. As a rule of thumb, any pure function implementing a mathematical function (like your case_one, which mathematically is a translation) is better coded as returning some result. Conversely, any program function which has mostly side effects is often coded as returning void. For cases in between, use your common sense, and look at existing practice -their source code- in existing free software projects (e.g. on github). Often a side effecting procedure might return some error code (or some success flag). Read documentation of printf & scanf for good examples.
Notice also that many ABIs and calling conventions are passing the result (and some arguments) in processor registers (and that is faster than passing thru memory).
Notice also that C has only call by value.
Some programming languages have only functions returning one value (sometimes ignored, or uninteresting), and have just expressions, without any notion of statement or instruction. Read about functional programming. An excellent example of a programming language with only value returning functions is Scheme, and SICP is an excellent introductory book (freely available) to programming that I strongly recommend.
The first approach is preferred, where you return a value. The second can be used when multiple values are computed by the function.
For example, the function strtol has this prototype:
long strtol(const char *s, char **endp, int base);
strtol attempts to interpret the initial portion of the string pointed to by s as the representation of a long integer expressed in base base. It returns the converted value with a return statement, and stores a pointer to the character that follows the number in s into *endp. Note however that this standard function should have returned 3 values: the converted value, the updated pointer and a success indicator.
There are other ways to return multiple values:
returning a structure.
updating a structure to which you receive a pointer.
C offers some flexibility. Sometimes different methods are equivalent and choosing one is mostly a matter of conventions, personal style or local practice, but for the example you give, the first option is definitely preferred.
int main()
{
int iStrangeArrayOutter[11];
iStrangeArrayOutter[7] = 5;
testFunc (iStrangeArrayOutter);
return 0;
}
int testFunc (int iStrangeArray[3])
{
printf ("%d\r\n", iStrangeArray[7]);
return 0;
}
What does the int iStrangeArray[3] part of the function declaration reveal?
Arrays are automatically converted to a pointer to its first element when used as function argument, so this function signature:
int testFunc(int iStrangeArray[3])
is equivalent to:
int testFunc(int iStrangeArray[])
or
int testFunc(int *iStrangeArray)
The size of the array is ignored, it's only useful as a signal to the programmer, not to the compiler. As for the why, because it's what the C standard says.
That may be a hint to readers that the length of iStrangeArray should be three, therefore it could act like part of the API documentation.
However, just like any other documentations that cannot be verified by compilers (or other tools), when the related code evolved, documentations and the code they tried to explain may become asynchronous, at this time (and it looks like this is exactly what happened in your case), this "documantation" could become misleading and will confuse readers.
If you take a look at what int iStrangeArray[3] is in your function, you'll see this is still just a pointer. As you may know, pointers have no idea about the size of the area they point at, maybe except for the data type of a single element. So yes, technically it does not make difference if you replace it with int iStrangeArray[] or int *iStrangeArray. However, this may be of much use for readability of your code.
We are currently developing an application for a msp430 MCU, and are running into some weird problems. We discovered that declaring arrays withing a scope after declaration of "normal" variables, sometimes causes what seems to be undefined behavior. Like this:
foo(int a, int *b);
int main(void)
{
int x = 2;
int arr[5];
foo(x, arr);
return 0;
}
foo is passed a pointer as the second variable, that sometimes does not point to the arr array. We verify this by single stepping through the program, and see that the value of the arr array-as-a-pointer variable in the main scope is not the same as the value of the b pointer variable in the foo scope. And no, this is not really reproduceable, we have just observed this behavior once in a while.
This is observable even before a single line of the foo function is executed, the passed pointer parameter (b) is simply not pointing to the address that arr is.
Changing the example seems to solve the problem, like this:
foo(int a, int *b);
int main(void)
{
int arr[5];
int x = 2;
foo(x, arr);
return 0;
}
Does anybody have any input or hints as to why we experience this behavior? Or similar experiences? The MSP430 programming guide specifies that code should conform to the ANSI C89 spec. and so I was wondering if it says that arrays has to be declared before non-array variables?
Any input on this would be appreciated.
Update
#Adam Shiemke and tomlogic:
I'm wondering what C89 specifies about different ways of initializing values within declarations. Are you allowed to write something like:
int bar(void)
{
int x = 2;
int y;
foo(x);
}
And if so, what about:
int bar(int z)
{
int x = z;
int y;
foo(x);
}
Is that allowed? I assume the following must be illegal C89:
int bar(void)
{
int x = baz();
int y;
foo(x);
}
Thanks in advance.
Update 2
Problem solved. Basically we where disabling interrupts before calling the function (foo) and after declarations of variables. We where able to reproduce the problem in a simple example, and the solution seems to be to add a _NOP() statement after the disable interrupt call.
If anybody is interested I can post the complete example reproducing the problem, and the fix?
Thanks for all the input on this.
That looks like a compiler bug.
If you use your first example (the problematic one) and write your function call as foo(x, &arr[0]);, do you see the same results? What about if you initialize the array like int arr[5] = {0};? Neither of these should change anything, but if they do it would hint at a compiler bug.
In your updated question:
Basically we where disabling interrupts before calling the function (foo) and after declarations of variables. We where able to reproduce the problem in a simple example, and the solution seems to be to add a _NOP() statement after the disable interrupt call.
It sounds as if the interrupt disabling intrinsic/function/macro (or however interrupts are disabled) might be causing an instruction to be 'skipped' or something. I'd investigate whether it is coded/working correctly.
You should be able to determine if it is a compiler bug based on the assembly code that is produced. Is the assembly different when you change the order of the variable declarations? If your debugger allows you, try single stepping through the assembly.
If you do find a compiler bug, also, check your optimization. I have seen bugs like this introduced by the optimizer.
Both examples look to be conforming C89 to me. There should be no observable difference in behaviour assuming that foo isn't accessing beyond the bounds of the array.
For C89, the variables need to be declared in a list at the start of the scope prior to any assignment. C99 allows you to mix assignment an declaration. So:
{
int x;
int arr[5];
x=5;
...
is legal c89 style. I'm surprised your compiler didn't throw some sort of error on that if it doesn't support c99.
Assuming the real code is much more complex, heres some things i would check, keep in mind they are guesses:
Could you be overflowing the stack on occasion? If so could this be some artifact of "stack defense" by the compiler/uC? Does the incorrect value of &foo fall inside a predictable memory range? if so does that range have any significance (inside the stack, etc)?
Does the mcu430 have different ranges for ram and rom addressing? That is, is the address space for ram 16bit while the program address space 24bit? PIC's have such an architecture for example. If so it would be feasible that arr is getting allocated as rom (24bit) and the function expects a pointer to ram (16bit) the code would work when the arr was allocated in the first 16bit's of address space but brick if its above that range.
Maybe you have at some place in your program in illegal memory write which corrupts your stack.
Did you have a look at the disassembly?
A coding style presentation that I attended lately in office advocated that variables should NOT be assigned (to a default value) when they are defined. Instead, they should be assigned a default value just before their use.
So, something like
int a = 0;
should be frowned upon.
Obviously, an example of 'int' is simplistic but the same follows for other types also like pointers etc.
Further, it was also mentioned that the C99 compatible compilers now throw up a warning in the above mentioned case.
The above approach looks useful to me only for structures i.e. you memset them only before use. This would be efficient if the structure is used (or filled) only in an error leg.
For all other cases, I find defining and assigning to a default value a prudent exercise as I have encountered a lot of bugs because of un-initialized pointers both while writing and maintaining code. Further, I believe C++ via constructors also advocates the same approach i.e. define and assign.
I am wondering why(if) C99 standard does not like defining & assigning. Is their any considerable merit in doing what the coding style presentation advocated?
Usually I'd recommend initialising variables when they are defined if the value they should have is known, and leave variables uninitialised if the value isn't. Either way, put them as close to their use as scoping rules allow.
Instead, they should be assigned a default value just before their use.
Usually you shouldn't use a default value at all. In C99 you can mix code and declarations, so there's no point defining the variable before you assign a value to it. If you know the value it's supposed to take, then there is no point in having a default value.
Further, it was also mentioned that the C99 compatible compilers now throw up a warning in the above mentioned case.
Not for the case you show - you don't get a warning for having int x = 0;. I strongly suspect that someone got this mixed up. Compilers warn if you use a variable without assigning a value to it, and if you have:
... some code ...
int x;
if ( a )
x = 1;
else if ( b )
x = 2;
// oops, forgot the last case else x = 3;
return x * y;
then you will get a warning that x may be used without being initialised, at least with gcc.
You won't get a warning if you assign a value to x before the if, but it is irrelevant whether the assignment is done as an initialiser or as a separate statement.
Unless you have a particular reason to assign the value twice for two of the branches, there's no point assigning the default value to x first, as it stops the compiler warning you that you've covered every branch.
There's no such requirement (or even guideline that I'm aware of) in C99, nor does the compiler warn you about it. It's simply a matter of style.
As far as coding style is concerned, I think you took things too literally. For example, your statement is right in the following case...
int i = 0;
for (; i < n; i++)
do_something(i);
... or even in ...
int i = 1;
[some code follows here]
while (i < a)
do_something(i);
... but there are other cases that, in my mind, are better handled with an early "declare and assign". Consider structures constructed on the stack or various OOP constructs, like in:
struct foo {
int bar;
void *private;
};
int my_callback(struct foo *foo)
{
struct my_struct *my_struct = foo->private;
[do something with my_struct]
return 0;
}
Or like in (C99 struct initializers):
void do_something(int a, int b, int c)
{
struct foo foo = {
.a = a,
.b = b + 1,
.c = c / 2,
};
write_foo(&foo);
}
I sort of concur with the advice, even though I'm not altogether sure the standard says anything about it, and I very much doubt the bit about compiler warnings is true.
The thing is, modern compilers can and do detect the use of uninitialised variables. If you set your variables to default values at initialisation, you lose that detection. And default values can cause bugs too; certainly in the case of your example, int a = 0;. Who says 0 is an appropriate value for a?
In the 1990s, the advice would've been wrong. Nowadays, it's correct.
I find it highly useful to pre-assign some default data to variables so that i don't have to do (as many) null checks in code.
I have seen so many bugs due to uninitialized pointers that I always advocated to declare each variable with NULL_PTR and each primitivewith some invalid/default value.
Since I work on RTOS and high performance but low resource systems, it is possible that the compilers we use do not catch non-initialized usage. Though I doubt modern compilers can also be relied on 100%.
In large projects where Macro's are extensively used, I have seen rare scenarios where even Kloclwork /Purify have failed to find non-initialized usage.
So I say stick with it as long as you are using plain old C/C++.
Modern languages like .Net can guarantee to initialize varaibles, or give a compiler error for uninitialized variable usage. Following link does a performance analysis and validates that there is a 10-20% performance hit for .NET. The analysis is in quite detail and is explained well.
http://www.codeproject.com/KB/dotnet/DontInitializeVariables.aspx