Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I'm writing code for an embedded system. The compiler is a GCC derivative.
Is the following code correct?
void *voidPointer = 0;
int (*functionPointer)(int a);
int testFunction(int a)
{
return(a+1);
}
void registerFunction(void *pvFunctionAddress)
{
voidPointer = pvFunctionAddress;
}
main()
{
...
registerFunction(testFunction);
functionPointer = voidPointer;
x = functionPointer(17);
...
}
Now x should have the value 18.
The compiler does not show an error - but is this correct?
Or do we overwrite some memory on the stack.
Thanks.
No, it can never be "correct" since strictly speaking C forbids conversions between void * and function pointers.
If it works, it's because a particular compiler allows it for that particular target (operating system + hardware combination).
Strictly speaking, according to the C standard, a void* is not guaranteed to be able to hold a function pointer. I believe that POSIX does require that a function pointer be able to be stored in a void* (in order to support the dlsym() function). See https://stackoverflow.com/a/12359083/12711
Let's say it like this:
In C a function is identified by the address of the first instruction in the appropriate assembly that begins it's execution and it's calling convention, thus a void* is a valid storage class to store it if the calling convention is a compile-time constant. For most commonly used CPU architectures it is.
If your code works with your compiler for your target hardware then it it correct in that sense.
Here is a simple comparison:
uintptr_t i = NULL;
is valid C because uintptr_t (normally unsigned long int) is the same storage class as void * (type of NULL).
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include<stdio.h>
void main() {
const int convalue=64;
int *point;
point = &convalue;
(*point)++;
printf("address of point is %p address of convalue is %p\n",point,&convalue);
printf("convalue is %d and point is %d\n",convalue,*point);
}
How can i modify the constant variable value
How can i modify the constant variable value
You cannot change the value of a constant1 after initialisation. That's what "constant" means.
You can change the program by removing the const qualifier. Then you can change the value. Or, you can conditionally choose another value during initialisation.
1 Except if the constant is of class type, then you can change mutable members of the object.
void main()
The pogram is ill-formed. main must return int in C++. It may not return void.
point = &convalue;
The pogram is ill-formed. A pointer to const doesn't implicitly convert to pointer to non-const. The type system of the language protects you from making mistakes such as this.
(*point)++;
The behaviour of the program is undefined. Const objects must not be modified. This is a bug. Don't write this in a program.
We can't and should never try to modify the value of a const variable. Also,
Any attempt to modify a const object results in undefined behavior.
Also,
note that undefined behavior means anything can happen including but not limited to program being successfully compiled and giving your expected output. But don't rely on the output of a program that has undefined behavior.
For more reading on undefined behavior you can refer to undefined behavior's documentation which mentions:
there are no restrictions on the behavior of the program.
Mistake 2
There is another mistake(in addition to undefined behavior) in your program(in C++). In particular, you should replace
int *point;//INCORRECT
with
const int *point;//CORRECT, note i have added const here
Mistake 3
You should replace void main() with
int main()
Because void main() is not standard C++ as Bjarne Stroustrup made this quite clear in this article
The definition void main() is not and never has been C++, nor has it even been C.
Simply – you can't. "Constant" is constant.
If you need to, you have to use variable instead.
Anyway, there is one possibility to get what you (maybe) want – preprocessor. Question is a bit strange, so I think you could be satisfied by that.
Using preprocessor you can determine what is the initial value of const. (And more, but that's not this case.) Still you can't modify it after it's initialized, but maybe it will be enough for you. For example:
#include<stdio.h>
void main() {
const int convalue=
#ifdef CLI_PROVIDED
CLI_PROVIDED;
#undef CLI_PROVIDED
#else
64;
#endif
int *point;
point = &convalue;
(*point)++;
printf("address of point is %p address of convalue is %p\n",point,&convalue);
printf("convalue is %d and point is %d\n",convalue,*point);
}
Normal compilation will initialize const with value 64. Compilation with option g++ -DCLI_PROVIDED=123 will modify initial value of const BEFORE compilation (this is just text operation) and then compile it with value 123.
Preprocessor is working with code before compilation.
If you want to (for example) create program for multiple operating systems, it will be useful.
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 needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I can pass arguments to a function in C in the following manner without any warnings or errors using gcc on ubuntu-64bit:
void func(char* test){
// do something here
}
void main() {
func((char*) "smaps");
}
I did not find a lot of examples about passing anonymous parameters to functions in C apart from one comment on a similar question about C++. I am thinking of using this technique (a lot) in my code which would be compiled on multiple AMD64/ARM devices as they become available (with mostly debian-based OSes). My question is, is this compiler-specific?
Output of gcc --version:
$ gcc --version
gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406
UPDATE: Even though I think 4386427's was good enough for me, I would explain a bit more about the question as it was put on hold. I have a script which makes several calls to a specific function which takes in a char** as argument. I was of the view that I would need to explicitly declare a char** separately and pass it to the function by name every time I made a call to the function. I thought it would be more convenient to declare a string and pass it to the function at the same time; something like:
func( (char**) {"first_string", "second_string"} ).
My initial concern was is this allowed in C generally or is this a compiler-specific feature? 4386427's answer suggests that it is not compiler-specific, however I should be careful that the char** passed to the function would be immutable.
All parameters in C are passed by value. No information about the original object from which the value came is passed to the called function. In this sense, all C arguments are anonymous; no information about the identifier used in the calling function is passed.
In func((char*) "smaps");, the string literal "smaps" is converted to a pointer to char. Only the value of the pointer is passed to func. This is standard C.
(If you do want to pass information about an object to a function, you must do that manually. For example, you can take the address of an object and pass the resulting pointer to the function. Or you can pass the number of elements in an array to a function, along with the address of the first element.)
(In C, string literals such as "smaps" are automatically converted to a pointer to their first character, so you do not need to manually convert them with a char * cast. [This automatic conversion does not occur when the string literal is the operand of sizeof, _Alignof, or & or when it is used to initialize an array.])
It depends on what you are doing in the function. As long as you don't try to modify what test is pointing to, there is no problem. To indicate that it can't be changed, it is good to add const.
Like this the code is fine:
#include <stdio.h>
void func(const char* test){
printf("%s\n", test);
}
int main(void) {
func("smaps1");
func("smaps2");
func("smaps3");
func("smaps4");
return 0;
}
But if you try to change the value like:
void func(char* test){
test[0] = 'A';
printf("%s\n", test);
}
you have undefined behavior because modifying a string literal is undefined behavior.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Is the following code in C correct? I am not 100% sure about the scope of function parameter "a":
void method(int a)
{
MyStruct mystruct;
mystruct.value = (void*) (&a);
nested_method_call(mystruct);
}
Let's assume it's:
void method(int a)
{
MyStruct x;
struct.value = (void*) a;
nested_method_call(x);
}
since struct cannot be used as a variable name.
a's scope is the function, so it is alive during nested_method_call, however, that is absolutely irrelevant because your nested_method_call isn't referring to it -- it's using a copy of a reinterpreted as void*. (Such reintepretation makes the code quite unportable and unusual, by the way. It might be a mistake.)
Edit:
void method(int a)
{
MyStruct mystruct;
struct.value = (void*) &a;
nested_method_call(mystruct);
}
is valid (though it's usually a good idea to pass structs by pointer because it's faster for any but very small structs). &a is a valid reference until the } of method.
You also shouldn't need that cast. If .value is void*, you don't need it. If it isn't, the cast makes &a convertible to any other data pointer, which is potentially a dangerous hole in the type system.
First of all, struct is a keyword in C and cannot be used as a variable name, so this is wrong code.
After that, casting an integer to pointer (and vice-versa) is implementation defined behaviour. You should better use uintptr_t for better, if you have to get that conversion done.
That said, from the basic premises of your question, the logic behind the code seems legit, there's no problem with the scope. In case you meant to ask about the lifetime ["The lifetime of an object is the portion of program execution during which storage is
guaranteed to be reserved for it"], then, it is until the end of the method() function and you're using it inside that limit, so you're good to go.
Corrected code: struct.value = (void*)&a;. Also some other validation needs to be done.
So, if you fully correct your code so that it complies properly then Correct word would be Lifetime instead of Scope. Lifetime of a will be till the end of function method. Therefore, a can still be accessed inside nested_method_call via pointer struct.value assuming type of struct.value is int*.
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 8 years ago.
Improve this question
I define a function, let's say myfun in file2.c. myfun returns a float value. In file1.c I don't have any declaration for this function. I directly call myfun without any prior declaration and assign it's return type to an integer variable, let's call it retValInt. I compile them together. When I print retValInt, it gives me garbage. Why doesn't it cast the returned value and give the appropriate integer?
The following is the exact code:
//file1.c
#include<stdio.h>
int main()
{
int retValInt = myfun(123.456);
printf("The value returned is %d\n",retValInt);
return 0;
}
//------------------------
//file2.c
float myfun(float a)
{
return a;
}
I expected the output to be 123, but it is 446676599.
How could the compiler possibly know, when compiling main, that myfun returns a float that needs to be cast to an int?
You're asking why the compiler didn't make the code do something it could not possibly have known it needed to make the code do. So the answer is obvious -- the compiler had no way to know that's what you wanted. In fact, it is reasonable for the compiler to assume that if you wanted it to do that, you would have told it to. So one can argue that the behavior you seem to expect would actually be incorrect and quite baffling. (You never told the compiler to do that, so doing it would be bad.)
In C, specifically in C89 (but not in C99 or C11!), functions that have not been declared are implicitly assumed to have return type int. If your actual function does not have that return type, your program is ill-formed (it has undefined behaviour), and no diagnostic is required.
Your code is not valid C99, but compiler support for C99 is half-hearted at best.
To write a prototype before using the function.
float myfun(float);
int main()