Variable in C with a limited range of values

How can I have a variable in C whose value should only be from 20 to 520? I want to limit this variable assignment to values ​​from 20 to 520? In case I take an enumeration whose value should start with 20, I still need to define another 519 values ​​inside the enum.

+5
source share
5 answers

C is not able to express directly what you want. Note that even enum does not enforce valid values. You can assign any value to the base type enum .

You can always come up with your own logic, for example. if this is part of the object you are modeling as a struct:

 struct foo { unsigned bar; }; // [...] int foo_setBar(struct foo *self, unsigned val) { if (val < 20 || val > 520) return -1; self->bar = val; return 0; } 
+9
source

How can I get a variable in C whose value should be only from 20 to 520?

In C there is no such data type.

Even if the range was something close to the boundaries of some types, the danger of overflow or overflow would be all the same (imagine an unsigned int , for example, where you want the lower border to be 0, but someone might exceed this binding).


What you can do is write your own structures, accessors and / or listings to achieve this. If interested, read Paul R's answer. However, I do not urge you to do this.

I would do this if, for example, the variable had to be populated by the user:

 int v; do { scanf("%d", &v); } while(!(v >= 20 && v <= 520)); 

so that the user requests again and again until his input meets the criteria.


PS: That sounds like an XY question.

+5
source

Unfortunately, C does not provide access control for members of the structure. So unsuccessful at first.

You should (try?) Get around this restriction in any suitable way. You can hide data from the user:

type.h:

 #include <stdbool.h> struct TheType; typedef struct TheType TheType; unsigned short get(TheType const* type); bool set(TheType* type, unsigned short value); 

type.c:

 struct TheType { unsigned short value; } unsigned short get(TheType const* type) { return type->value; } bool set(TheType* type, unsigned short value) { if(value < 20 || value > 520) return false; type->value = value; return true; } 

This is due to another drawback, as other functions, such as sizeof , also become unusable ... We should probably provide at least the size_t sizeofTheType() function size_t sizeofTheType() , which allows the user to allocate the appropriate amount of memory, and possibly other things.

+5
source

Good thing you can:

 typedef enum { F_FIRST = 20, E_LAST = 520 } MySpecialEnum; 

However, this range will not be applied at compile time or at run time, but you can use it to explicitly check the range and as an aid to self-documenting code.


Remember that this is C, a low-level language. If you want to check variables with given ranges at runtime, consider a language such as Pascal, where you can declare a subrange variable as follows:
 PROGRAM test; VAR x : 20 .. 520; BEGIN x := 20; // OK x := 1000; // error END. 

and then you get a range check at runtime without any explicit code. Of course, there is a penalty for doing this.

+2
source

This is possible in C ++. But as for using the C syntax, this is not possible. Therefore, you will have to use ugly DSLs as shown below.

 #include <stdio.h> #include <assert.h> #define DEFINE_VAR(x) int ____________________ ## x = 0; #define VARIDATE_VAR(x) \ assert(20 <= ____________________ ## x && ____________________ ## x <= 520); #define SET_VAR(x, y) { \ ____________________ ## x = y; \ VARIDATE_VAR(x) \ } #define GET_VAR(x) ____________________ ## x int main(int argc, char* argv[]) { DEFINE_VAR(n); SET_VAR(n, 30); return 0; } 
+1
source

Source: https://habr.com/ru/post/1269295/


All Articles