Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
What are the practical applications of compound literals? I am not quite sure how an address of an unnamed region of storage could be useful.
int *pointer = (int[]){2, 4};
I found them mentioned here: https://en.cppreference.com/w/c/language/compound_literal
Here are some great ones:
Working around interfaces that take a pointer to input rather than a value (possibly to return an updated value you don't have any reason to care about):
y = accept(x, &sa, &(socklen_t){sizeof sa});
Implementing functions with named and default-zero/null arguments:
#define foo(...) foo_func(&(struct foo_args){__VA_LIST__})
foo(.a=42, .b="hello" /* .c = NULL implicitly */);
Implementing custom formats for printf (automatically getting per-macro-instantiation temp buffer):
#define fmt_mytype(x) fmt_mytype_func((char[MAX_NEEDED]){""}, x)
printf("...%s...", ..., fmt_mytype(foo), ...);
Compound literals can be used for arrays, but they are just as useful to initialize structs, allowing you to put a complicated initializations in one line, making the code easier to read, and less tedious to write.
Like so:
typedef struct{
int a,b,c;
char *d;
}type;
int main(){
type t=(type){.a=0,.b=1,.c=2,.d="Hello world"};
...
Without a compound literal that would have been at least four lines of code.
They can also simplify transformation functions:
typedef struct{
int a;
int b;
}twoInts;
twoInts swap(twoInts in){
return (twoInts){.a=in.b,.b=in.a};
}
They can be useful when you don't have control over the left part. If possible, you would probably use int pointer[] = {2, 4};. But what if the left part is defined by e.g. an external API, and you want to assign to it? The compound literal would be an option.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
People have marked this post as a duplicate of this but it's actually not because I'm not asking what is a composite type but what is its purpose and i gave a use case where it could cause a harm for software developers and then asked if this should be undefined behavior instead.
I was reading that part of the C11 standard about composite types and i was just like : Why the heck on earth would someone do something like that ?
I mean i can't see anything interesting about that. I think this is very confusing for programmers. For the sake of example, let's say we had a function void f() that people used everywhere in the software, they just declare extern void f() and use it. The definition of the function is somewhere programmers don't care about; then one day, one smart guy needed to add an argument to that function and changed the definition to something like void f(int *ptr) {/* ..*/ return *ptr;}. The software will still compile happily but god, all that legacy code that used the old interface is screwed up with segfaults.
The code below is a demo :
/* main.c */
#include <stdio.h>
int f ();
int p = 5;
int main ()
{
int r = f (); /* This call will cause segfault */
int s = f (&p);
printf ("r=%d / s=%d \n", r, s);
return 0;
}
/* another_unit.c */
int f (int *ptr)
{
return *ptr;
}
I don't see the purpose of such a thing. In my opinion that should be undefined behavior or at least why do compilers like GCC don't say anything about it ?
The point in your example is that the function f() has no prototype, and the other one has one. The form of declaration without comes from early C and is marked as obsolete since many years.
The construct of composite type between the two helped when prototypes were introduced into C to accommodate between old code and new code.
Calling a function with arguments that do not correspond to the parameters that it expects has undefined behavior, so with that mechanism you have to know what you are doing.
In short, don't use declarations without prototype. They are outdated since long and might be removed from the C standard at any time.
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 6 years ago.
Improve this question
Why is there no increment operator for enums in C? Even if the corresponding integer values are user-defined it does make perfectly sense to me to iterate with ++ to the next member.
To make it more clear
typedef enum myenum t_myEnum;
enum myenum {
eMember1,
eMember2
}
t_myEnum bla = eMember1;
Now I ask what is the reason against bla++ yields eMember2.
User defined assignments to integers values like
enum myenum {
eMember1 = 0,
eMember2 = 10
}
shouldn't be an obstacle in my opinion.
I am sure it is a drawback of C and C++.
Initially enumerations are considered as sets of integer constants as an alternative for the directive #define. Thus an enumeration in C is a common name for a set of such constants. They were made as simple as possible.:)
There was made a step ahead in C++ and enumerators started to have types of their enumerations. Also you can overload operators ++ for enumerations though I agree with you that it would be better that these operators would be built-in.
For example enumerations could be implemented a similar way as std::initializer_list in C++.
So in my opinion there are only historical reasons for the absence of these operators.
An other drawback is impossibility to get the number of enumerators defined in an enumeration.
I would guess there is no such operator since the work-around is so trivial:
typedef enum
{
eMember1 = 0,
eMember2 = 10
} myenum;
const myenum TABLE [] =
{
eMember1,
eMember2
};
for(size_t i=0; i<sizeof(TABLE)/sizeof(*TABLE); i++)
{
do_something_with(TABLE[i]);
}
Similarly, you could use a const myenum* as iterator.
Another reason why such an operator doesn't exist might be that it doesn't make much sense. Lets pretend there was one, what do you think this code would do?
myenum e = eMember2;
e++;
And what would code like eMember1+1 mean? Value 1 or value 10? Again, there's no consistent logic to it.
Nothing in the C Standard prevent incrementing variables of enum types.
In your example, the typedef is incorrect because you have a forward reference to an enum type, but the following code demonstrates what I think your question is about:
#include <stdio.h>
typedef enum myenum {
eMember1,
eMember2,
} t_myEnum;
int main(void) {
t_myEnum bla = eMember1;
printf("bla=%d\n", bla);
printf("bla++=%d\n", bla++);
printf("bla=%d\n", bla);
return 0;
}
Output:
bla=0
bla++=0
bla=1
Of course the value of bla is just incremented by 1, it may correspond to another enumeration value or not, depending on the actual values of the enumeration values in the enum type.
There is no way to enumerate the defined values of a given enum type.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I was wondering how could I use a single sort function that does the sorting choosing from 2 different criteria.
I was thinking to implement the sort function(Sort) having a pointer to another function(Criteria) as an argument. That function Criteria provides me either the (let's say) name or the age of a student, using structures. So a single function that returns two types of data. I think it has to be a void. I want to use bubble sort but I have no idea on how to implement the Criteria function since I want it to return either a char or an int value.
Behave like qsort
qsort solves the problem by taking a pointer to a comparison function that takes two pointers to structures (left and right) and compares the values pointed at:
compare( left, right ){
if( left->field < right->field )
return -1;
if( left->field > right->field )
return 1;
return 0;
}
The types left and right are passed in as void* but cast to concrete types.
Different implementations of compare give different fields.
variant structure
The alternative is a union / struct
struct data {
enum Types type;
union {
double dblVal;
int intVal;
....;
} u;
};
The type signals the type of data in the union, and the members can then be appropriately read.
This is the approach taken by lua for its type system.
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 7 years ago.
Improve this question
When someone has a lot of variables, is it better to declare all the variables of the same type in one line or write one line for each variable declaration? (in terms of readability of the code)
for example
All in one line :
int my_rank, comm_size, processors_used, name_length, *x, *y;
double mean_value, variance, var_sum, *var_sums;
char string,*tmp,option;
Each on its own line:
int my_rank;
int comm_size;
int processors_used;
int name_length;
int *x;
int *y;
double mean_value;
double variance;
double var_sum;
double *var_sums;
char string;
char *tmp;
char option;
I would prefer the first over the second but i'm in a situation where i simply have about 19 integers and i think that either way makes the code look illegible and ugly.
I actually separated the declarations in logical blocks and grouped variables in the same declaration if they are correlated.
int my_rank, comm_size, processors_used, name_length;
int *x, *y, *send_counts, *displacement, num;
int max, min, loc_max, loc_min, *max_array, *min_array;
int i,option,sum,*sums;
double mean_value, variance, var_sum, *var_sums, *delta_vector, *local_delta;
char proc_name[MPI_MAX_PROCESSOR_NAME];
MPI_Status status;
Which do you think makes the code more readable?
It is mostly a matter of opinion whether you group definitions for local variables or separate them one per line. Here are some general remarks:
Local coding style may impose one over the other. Consistency with the rest of the project is valuable and helps readability.
Documenting some of these definitions with a short comment on the same line may be useful and prompts for separating them. Yet do not comment the obvious.
If you group definitions in logical blocks, do not mix pointers and variables on the same line. It is confusing to many readers.
Moving the definitions closer to where the variables are used also helps readability as it reduces the scope for these variables are reduces mental space as well, a limited resource.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
Sometimes I just get so confused about the syntax in C. In struct, everything is separated by a semicolon and there is one extra semicolon after the last member, while in enum, everything is separated by a comma and there is no extra comma at the end. I always forget the last semicolon in struct since it doesn't seem to make sense to me. Is there any good reason for designing it that way? I hope someone can point out why it is good so that I can get used to it, right now it makes the syntax really hard to memorize.
Perhaps the simplest way to memorize this is that structs and unions are basically nested scopes. They contain declarations, just lie functions or your "root" document (in global scope).
So, you declare struct members:
struct {
int member_a;
int member_b;
} ;
Kind of like how you declare globals or function members:
/* START OF FILE */
int global_a;
int global_b;
/* END OF FILE */
Enums are lists -- kind of like array declarations, or multiple variables, etc...:
int arr[] = {1, 2, 3}; //* see note below
enum Foo { FOO, BAR, BAZ };
int foo, bar, baz;
// multiple "sub-statements" in one statement
// note that this is generally considered bad practice.
foo++, bar++, baz = bar;
Or you could simply remember it this way: Semicolons are statement terminators (they end statements), while commas are separators (they come between elements).
(*note: arrays are an exception in that they optionally allow for a trailing comma. As to why they allow for that in arrays while they don't allow it for enums is beyond me)
In C:
A comma is a seperator. Between values. Example: enum.
A semicolon is a terminator. of Statements and declerations.