static initialization in c - c++

I have a function which is passed a list of ints, until one value is "-1" and calculates the minimum.
If the function gets called couple times, it is supposed to return the minimum between all calls.
So I wrote something like that:
int min_call(int num, ...)
{
va_list argptr;
int number;
va_start(argptr, num);
//static int min = va_arg(argptr, int); //////// the questioned line
static int all_min = -1;
int min = va_arg(argptr, int);
if (min != -1)
{
while ((number = va_arg(argptr, int)) != -1)
{
if (number < min)
{
min = number;
}
}
}
if (min < all_min || all_min == -1)
{
all_min = min;
}
return all_min;
}
I want to know something about the marked line... why can't I call it - the compiler says because the expression being used to initialize the static int is not constant.
For some reason I remember that I can initialize a static variable and know that the initializing statement will be called only once (the first time) it's written in C++.
If that line would be available it would have saved me couple variables.
Is there a difference between C and C++ in this matter?

Yes, C++ allows for statics to be lazily initialized at runtime. Effectively C++ turn static initialization into this:
static int XX_first_time = 1;
if (XX_first_time)
{
// run the initializer
XX_first_time = 0;
}
While this is convenient, it is not thread safe. The standard does not require this to be thread safe although some compilers have done that anyway (gcc 4.x does thread safe initialization unless explicitly requested not to with -fno-threadsafe-statics).
C requires statics be to have their value configured at compile time. Yes, this is more limited but is more in line with C doing little work for you behind your back (C can be thought of as portable assembly).

C static initialization must be done with constant values, i.e. something that is known at compile-time. Because your call to va_arg() won't resolve until runtime, you can't use it as a static initializer. You could assign a known-bad value to min at initialization and then simply call va_arg() after the variable has been initialized (John Dibling's example code does exactly that).
Also, it's important to note that static initialization only happens once per scope (in this case, your function), so even if your commented-out line worked, it would only be executed once and not each time the function is invoked (as I think you were expecting).

As others have said, in C, static variables must be initialized with compile-time constants. If you omit the initial value, it is taken as 0.
Now, about the logic in your function. I think the function is written much more clearly like this (I am not changing the form of the function):
#include <limits.h>
int min_call(int num, ...)
{
va_list argptr;
int number;
static int min = INT_MAX;
va_start(argptr, num);
while ((number = va_arg(argptr, int)) != -1)
if (number < min)
min = number;
va_end(argptr);
return min;
}
If num should also be included in the calculation of the minimum, then you will need an additional check along the lines of if (num < min) min = num;.
I also have trouble understanding if (min < all_min || all_min == -1 ) line. Since all_min was initialized to -1 in the beginning and then never touched, the if condition will always be true.
Note that the initialization of min is to INT_MAX and not INT_MIN as one of the comments says, and that we must call va_end().

You can't do what you're trying to do because the static is intialized before the program starts running -- argptr doesn't exist in context yet. You could try something like this:
va_start( argptr, num );
static bool init = 0;
static int min = -1;
if( !init )
{
min = va_arg( argptr, int );
init = true;
}
static int all_min = -1;

Static doesn't just mean it only gets set the first time you call it. It means that it's set at compile time. The compiler doesn't know how to call your va_arg function at compile time. (It doesn't make any sense until you're in run-time and running the program and passing it arguments.)
(edit - In C. Someone else has noted C++ is different.)

This doesn't exactly answer your question, but the other answers have done a good job of doing so already.
However, I think you are approaching this very simple problem from the wrong direction. If you want your functions to be portable and re-usable, you should try to minimize their side effects.
For example, instead of keeping state data in your function (evil), you should be keeping that data in a variable (or struct) local to the scope that is using it. Like this:
{
int min_so_far;
min_so_far = min_call(NULL, 4, 7, 2, -6, 3, -12);
min_so_far = min_call(&min_so_far, -11, 5, 3, 8, -3);
printf("%d\n", min_so_far); //should output -12
}
The first argument to min_call would be an int*, and if it was passed in as NULL, then the function would disregard it. Otherwise, each argument would be compared against the int that was passed in.
This isn't as convenient, but it's definitely safer, and you will be able to use this function in more than one place in the application. Thinking about the reusability of your code is a good habit to get into.

Related

C++ What would be the best way to set a maximum number for an integer in the function parameters

I have a problem. I will use a hypothetical example as I do not think that I need to use my actual function as it is kind of complex. This is the example:
int GetNumberTimesTwo(int num)
{
return num * 2;
}
Now, let's assume that if the Number is bigger than two something bad happens. Is there any way how I can force num to be less or equal than 2? Of course, I could do
int GetNumberTimesTwo(int num)
{
if (num > 2)
return;
return num * 2;
}
The problem is that this would be annoying as it just prevents this from happening, but I would like to know about this error before compiling. Meaning, is there something like int num < 2 that I can do?
In my dreams, it could be done like that:
int GetNumberTimesTwo(int num < 2)
{
return num * 2;
}
But as I said, in my dreams, and because I know C++, I know that nothing ever works like I would like it to work, therefore I have to ask what the correct way to do this is.
C++ What would be the best way to set a maximum number for an integer in the function parameters
There are basically two alternatives:
Decide how to handle invalid input at runtime.
Accept a parameter type whose all possible values are valid, thereby making it impossible to pass invalid input.
For 1. there are many alternatives. Here are some:
Simply document the requirement as a precondition and violating the precondition results in undefined behaviour. Assume that input is always valid and don't check for invalid values. This is the most efficient choice, but least safe.
Throw an exception.
Return std::expected (proposed, not yet standard feature) or similar class which contains either result, or error state.
For 2. There are no trivial fool-proof choices. For a small set of valid values, an enum class is reasonably difficult to misuse:
enum class StrangeInput {
zero = 0,
one = 1,
two = 2,
};
int GetNumberTimesTwo(StrangeInput num)
There is no way the compiler knows how to validate this, and if it does what would be the error? stop compiling?
The problem is that you are passing a variable to the function, In the universe of possible values of ints there are for sure values greater than 2 so how would the compiler know that in your execution you are never passing that amount.
This is a typical runtime validation, you should be validating the preconditions in your function and handle these scenarios in case unexpected values comes.
With template and/or constexpr, you might have some kind of check, but requires value known at compile time and possibly restrict available functions to call inside the function:
template <int N>
int GetNumberTimesTwo()
{
static_assert(N <= 2);
return N * 2;
}
constexpr int GetNumberTimesTwo(int num)
{
// only code valid for constexpr
// the restrictions has changed with standard
if (num > 2) throw std::runtime_error("out of range");
return num * 2;
}
constexpr int ok = GetNumberTimesTwo(1);
constexpr int ko = GetNumberTimesTwo(42); // Compile time error
int no_check1 = GetNumberTimesTwo(1); // ok at runtime
int no_check2 = GetNumberTimesTwo(42); // throw at runtime
this is the way to go:
int GetNumberTimesTwo(int num)
{
if (num > 2)
{
return 0;
}
return num * 2;
}
or throw an error:
int GetNumberTimesTwo(int num)
{
if (num < 0)
{
throw std::invalid_argument("count cannot be negative!");
}
return num * 2;
}

Local variable definied in an if statement hehaves unexpectedly

Originally I wanted to pack a bunch of statement into a single line so my stuff can be used as a simple macro inside an if.
I needed to do 3 things:
Create a local variable
Update that with a function
Check if the updated variable matches something else
Here's my quick draft code:
#include <iostream>
#include <stdint.h>
#define MAGIC_VALUE 42
bool MyMockedFunction(uint64_t* outElement)
{
*outElement = MAGIC_VALUE;
return true;
}
static const uint64_t global_should_match_this = MAGIC_VALUE;
int main()
{
// Originally I wanted to declare the variable in one single line (as a defined macro, which should be used in an IF statement)
// That's why I have so many things packed into the same line
// It may or may not (latter is more probable) a good idea, but that's not the question here
if (uint64_t generatedElement = 123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// I would expect generatedElement == MAGIC_VALUE
printf("Inside value: %llu\n", generatedElement);
}
else
{
printf("Unmatched\n");
}
return 0;
}
I understand that programatically it may not be foolproof and it's prone to misuse if I put it in a macro (also macros are evil), but in my case it would be a very controlled environment, just to make my code easier to read.
So, the question is here - why the generatedElement equals to 1 after running? Is it an undefined behaviour in any way?
I've checked in a compiler disassembler that it's 1 because in the end the comparison's value (is the expression true? yes -> 1 -> that's what is moved into the variable. But it looks unreasonable to me. Why would a compiler do so? :O Checked both on MSVC & GCC, both produces the same output.
Your condition is really:
uint64_t generatedElement = (123456 && MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
Which means you initialize generatedElement with the boolean result. And also lead to undefined behavior as you use the uninitialized (and indeterminate) value of generatedElement.
If your compiler support if statements with initializer (new in C++17) then you can do
if (uint64_t generatedElement = 123456; MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}
Otherwise you have to split up into separate variable definition and condition:
uint64_t generatedElement = 123456;
if (MyMockedFunction(&generatedElement) && global_should_match_this == generatedElement)
{
// ...
}

I'm trying to write a function that computes the numeric root of a number in C++, but get an error after compiling

int main(){
int sum_digits(int tiv) {
int sum = 0;
while (tiv > 0) {
sum += tiv % 10;
tiv /= 10;
};
return sum;
};
int num_root(int num) {
int root = sum_digit(int num);
while(root > 9) {
sum_digits(int root);
};
return root;
};
return 0;
}
This is the code that I have written the first function calculates the sum of the digis of a number. The second function uses a loop to calculate the sum of the digits repeatedly until a one digit numer is obtained (i.e. the numeric root).
But when I compile the code, this is what I get
5:29: error: a function-definition is not allowed here before '{' token (the first line of main)
22:2: error: expected '}' at end of input (the last line)
Some guidance would be appreciated, thanks in advance.
As people have indicated in the comments, you shouldn't define a function inside of another function like this.
int main(){
// This is defined inside of main
int sum_digits(int tiv) {
int sum = 0;
while (tiv > 0) {
I'd always encourage proper code indentation as that would have made this problem much more obvious.
Also, this isn't the correct way to do a function call:
int root = sum_digit(int num);
You don't need to include the int again here (in fact, it's not syntactically valid to do so) - it's already clear from the rest of your code that num is an int.
Same thing here:
while(root > 9) {
sum_digits(int root);
};
Also, you don't actually do anything with the return value of sum_digits, so this will literally do nothing. It will either be an infinite loop (if root is greater than 9), since the value of root never changes, or the loop won't ever run (if root is less than 9).
One final point: in order to have this program actually do anything, you'll have to call the functions from your main method with some value. Right now even if you fix the compilation errors the program won't work because you don't actually determine what values you want the root of and you never actually call the functions you wrote.
defining functions within functions is nothing you should do in c/c++. I think gcc supports this, but afaik its not standard conforming.
just declare and define your functions not within other functions. use anonymous namespaces if you want to hide them from your public api

c++ Need for typecasting int to unsigned int

I had this code as part of a C++ project
unsigned int fn() {
//do some computations
int value = ....
if(value <= 0)
return 0;
return (unsigned int)value;
}
I don't get the need to use the cast at the last return statement since all negative numbers will be caught in the if statement(hence returning 0).
And moreover this function fn is called from another function (whose return type is int) that simply returns the value returned by fn.
Thanks..
The purpose is to silence the compiler warning that could otherwise be issued.
I think that it really changes nothing
I personally run the same code for different scenarios and it appears the last cast can be done away with.

C++ use `const int` as looping variable?

I want to write code that compiles conditionally and according to the following two cases:
CASE_A:
for(int i = 1; i <= 10; ++i){
// do something...
}
CASE_B: ( == !CASE_A)
{
const int i = 0;
// do something...
}
That is, in case A, I want to have a normal loop over variable i but, in case B, i want to restrict local scope variable i to only a special case (designated here as i = 0). Obviously, I could write something along the lines:
for(int i = (CASE_A ? 1 : 0); i <= (CASE_A ? 10 : 0); ++i){
// do something
}
However, I do not like this design as it doesn't allow me to take advantage of the const declaration in the special case B. Such declaration would presumably allow for lots of optimization as the body of this loop benefits greatly from a potential compile-time replacement of i by its constant value.
Looking forward to any tips from the community on how to efficiently achieve this.
Thank you!
EDITS:
CASE_A vs CASE_B can be evaluated at compile-time.
i is not passed as reference
i is not re-evaluated in the body (otherwise const would not make sense), but I am not sure the compiler will go through the effort to certify that
Assuming, you aren't over-simplifying your example, it shouldn't matter. Assuming CASE_A can be evaluated at compile-time, the code:
for( int i = 0; i <= 0; ++i ) {
do_something_with( i );
}
is going to generate the same machine code as:
const int i = 0;
do_something_with( i );
for any decent compiler (with optimization turned on, of course).
In researching this, I find there is a fine point here. If i gets passed to a function via a pointer or reference, the compiler can't assume it doesn't change. This is true even if the pointer or reference is const! (Since the const can be cast away in the function.)
Seems to be the obvious solution:
template<int CASE>
void do_case();
template<>
void do_case<CASE_A>()
{
for(int i = 1; i <= 10; ++i){
do_something( i );
}
}
template<>
void do_case<CASE_B>()
{
do_something( 0 );
}
// Usage
...
do_case<CURRENT_CASE>(); // CURRENT_CASE is the compile time constant
If your CASE_B/CASE_B determination can be expressed as a compile time constant, then you can do what you want in a nice, readable format using something like the following (which is just a variation on your example of using the ?: operator for the for loop initialization and condition):
enum {
kLowerBound = (CASE_A ? 1 : 0),
kUpperBound = (CASE_A ? 10 : 0)
};
for (int i = kLowerBound; i <= kUpperBound; ++i) {
// do something
}
This makes it clear that the for loop bounds are compile time constants - note that I think most compilers today would have no problem making that determination even if the ?: expressions were used directly in the for statement's controlling clauses. However, I do think using enums makes it more evident to people reading the code.
Again, any compiler worth its salt today should recognize when i is invariant inside the loop, and in the CASE_B situation also determine that the loop will never iterate. Making i const won't benefit the compiler's optimization possibilities.
If you're convinced that the compiler might be able to optimize better if i is const, then a simple modification can help:
for (int ii = kLowerBound; ii <= kUpperBound; ++ii) {
const int i = ii;
// do something
}
I doubt this will help the compiler much (but check it's output - I could be wrong) if i isn't modified or has its address taken (even by passing it as a reference). However, it might help you make sure that i isn't inappropriately modified or passed by reference/address in the loop.
On the other hand, you might actually see a benefit to optimizations produced by the compiler if you use the const modifier on it - in the cases where the address of i is taken or the const is cast away, the compiler is still permitted to treat i as not being modified for its lifetime. Any modifications that might be made by something that cast away the const would be undefined behavior, so the compiler is allowed to ignore that they might occur. Of course, if you have code that might do this, you have bigger worries than optimization. So it's more important to make sure that there are no 'behind the back' modification attempts to i than to simply marking i as const 'for optimization', but using const might help you identify whether modifications are made (but remember that casts can continue to hide that).
I'm not quite sure that this is what you're looking for, but I'm using this macro version of the vanilla FOR loop which enforces the loop counter to be const to catch any modification of it in the body
#define FOR(type, var, start, maxExclusive, inc) if (bool a = true) for (type var##_ = start; var##_ < maxExclusive; a=true,var##_ += inc) for (const auto var = var##_;a;a=false)
Usage:
#include <stdio.h>
#define FOR(type, var, start, maxExclusive, inc) if (bool a = true) for (type var##_ = start; var##_ < maxExclusive; a=true,var##_ += inc) for (const auto var = var##_;a;a=false)
int main()
{
FOR(int, i, 0, 10, 1) {
printf("i: %d\n", i);
}
// does the same as:
for (int i = 0; i < 10; i++) {
printf("i: %d\n", i);
}
// FOR catches some bugs:
for (int i = 0; i < 10; i++) {
i += 10; // is legal but bad
printf("i: %d\n", i);
}
FOR(int, i, 0, 10, 1) {
i += 10; // is illlegal and will not compile
printf("i: %d\n", i);
}
return 0;
}