Why does this code not compile? - c

Could anyone please explain why this code compiles :
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv [])
{
FILE *ptr;
char string[10] = "Testing";
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
fwrite(string,sizeof(string[0]), sizeof(string)/sizeof(string[0]), ptr);
}
Yet this does not : Gives an Error C2065:'string' : undeclared identifer
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv [])
{
FILE *ptr;
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
char string[10] = "Testing";
fwrite(string,sizeof(string[0]), sizeof(string)/sizeof(string[0]), ptr);
}
I am using Visual Studio 2010 on a Windows 7 Machine.
Thanks

Visual Studio uses the old C89/90 C. In that older C version, you can't mix declarations and code.
All your declarations must go on top. That's why the second example fails to compile.
// This a declaration
FILE *ptr;
// This is code
ptr = fopen("C:\\Users\\Jordan\\Desktop\\Hello.txt", "wb");
// This is another declaration. Not Allowed in C89/C90!!!
char string[10] = "Testing";

In (the C89 version of) C, all variables must be declared at the top of the block (the function, in this case). In your first example, you're doing that, in your second one you're not.

If you saved this file with a .c extension the compiler is interpreting it as a C source file, and since VC++ support for C is for C89, the C89 rules for variable declaration apply; in particular, in C89 you must declare all the local variables at the beginning of their block.

Related

How does #define carries the function name in c?

After working for more than 10 years, today a code caught my eye, I am unable to understand the function name defined inside a function gets printed in the output/log without being passed as an argument in macro or being defined as a global variable. Please help me understanding the internal. Please see the screenshot for the reference.
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
Output:
Hello WorldMAIN
C preprocessor macros simply do text replacement. They have no semantic awareness of your program.
This:
#include <stdio.h>
#define x printf("%s", f);
int main()
{
char* f = "MAIN";
printf ("Hello World");
x;
return 0;
}
Becomes:
#include <stdio.h>
int main()
{
char* f = "MAIN";
printf ("Hello World");
printf("%s", f);;
return 0;
}
Please note that if there is no f declared when this macro is used, you will see a compiler error. If f is declared, but is not a char *, you should see compiler warnings.
Some preprocessor macro best practices include (but are not limited to) using capitalized names, as x by convention looks like a variable or function name; and being careful about what syntactically significant symbols (in this case ;) you include in your macro text.
Hopefully this example was done for the sake of learning, because it is wholly unnecessary. Preprocessor macros wouldn't exist if they didn't serve a purpose, but beware they can easily obfuscate code.
Preprocessor macros are just text replacements. All #include statements are replaced with the content of the specified files. All occurrences of #define'd symbols are replaced with their specified text. All comments are omitted. Etc...
So, in your example:
/*...*/
#include <stdio.h>
#define x printf("%s", f);
int main() {
char *f = "MAIN";
printf("Hello World");
x;
return 0;
}
The preprocessor replaces all instances of x with the text printf("%s", f); before the processed code is then sent to the compiler. So, this is the code that the compiler actually sees:
// contents of <stdio.h> here...
int main() {
char *f = "MAIN";
printf("Hello World");
printf("%s", f);;
return 0;
}

Function pointer different behaviour in GCC and Arduino

In my C program I have a skeleton for a command interpreter. It works fine on Linux/GCC, but in Arduino it does not return the expected results.
Below find the PC code. I did the appropriate changes for Arduino, and it works except the return string (see second line from bottom in listing).
C-Code on PC (working):
#include <stdio.h>
char* help(char *s){
char *helpString="This is the help string\n";
return helpString;
}
typedef struct {
const char* command;
char* (*cmdExec)(char *s);
}S_COMMAND;
S_COMMAND cmdTable[]= {
{"he", help}
};
int main(void){
char *text;
printf("\n%s\t",cmdTable[0].command); // returns "he"
text = (cmdTable[0].cmdExec)("0");
/* returns help string on PC as expected, but garbage on Arduino */
printf("\n%s", text);
}
Thanks for the advice. I modified the code like follows (peeking at Node.JS), and it is working fine now on both platforms.
int help(char *req, char *res){
strcpy(res, "This is the help string...\n");
return 0;
}
typedef struct {
char* command;
int (*cmdExec)(char *request, char *result);
}S_COMMAND;
S_COMMAND cmdTable[]= {
{"he", help}
};
int main(void){
char text[20];
cmdTable[0].cmdExec("0", text);
}
This is valid C code (with the exception of the missing return statement in main), and a conforming C compiler should accept it and produce a working executable. In particular, your use of function pointers isn’t related to the problem at hand. Furthermore, the manual for avr-gcc does not mention any relevant restrictions. I don’t have an Arduino on hand to test the behaviour but if avr-gcc does not produce working code for the input you’ve shown then this suggests a bug in the compiler.
char* help(char *s){
char *helpString="This is the help string\n";
return helpString;
}
You're returning a local variable - it ceases to exist once you go out of scope from the function. That it works at all on any platform is pure luck as once it ceases to exist, trying to access the string is undefined behaviour.

ANSI C -> Arrays -> Variably modified at file scope

While I'm trying to explore possibilities of arrays in C in ANSI, I'm confronted with an issue. Here's my code:
#include <stdio.h>
#include <string.h>
static int MAXLIGNE = 5000;
char *ptrlig[MAXLIGNE]; // PTR SUR LA LIGNE DE TXT // GOT AN ISSUE :
// VARIABLY MODIFIED PTRLIG # FILESCOPE
int lirelignes(char *ptrlig[], int nlignes);
void ecrirelignes(char *ptrlig[], int nlignes);
void trirapide(char *ptrlig[], int gauche, int droite);
Error from the GCC :
VARIABLY MODIFIED PTRLIG at FILESCOPE
I've seen that 'const' type may create that kind of issues. I tried to make it like :
#include <stdio.h>
#include <string.h>
static int MAXLIGNE = 5000;
unsigned char *ptrlig[MAXLIGNE];
But that doesn't seem to change anything in this case.
The length of an array defined at file scope must be a compile time constant, and the value of another variable does not qualify as such.
If you want to use a name for the length of this array, you'll need to use a macro:
#define MAXLIGNE 5000
char *ptrlig[MAXLIGNE];
The macro does a direct text substitution, so after the preprocessor stage it is the same as char *ptrlig[5000];

How to pointer reference dynamic sized pointer to array?

I want to be able to reference variable sized array with a global pointer. But what kind of pointer do I use that will work with variable sizes of the array? In the example below, assume N will only be known at runtime (could be an argument for example) so compile time solutions won't work.
What I want to achieve:
main.c
some_sort_of_pointer *x;
main()
{
int N=256; //or N=64 or whatever
char (*LC)[N];
LC=malloc(1024);
x=LC;
memcpy(x[2],"hello world",11);
x[0][176]=123;
dostuff();
}
I'm sure there's an easy obvious way to do this but I can't seem to nail it. My first attempt at asking this was a mess so this time I'm hoping it's clear what I want to achieve.
OS Centos 6.5
compiler GCC 4.8 (using C99)
As at compile time the type to be referenced isn't given, a void pointer might help.
However only storing an untyped reference (what void * in fact is is) is not enough, as it is essential to also know the size of the (VL)array. So the latter also needs to be stored globally, as it can not be pulled from the memory referenced.
An example how this can be achieve is given below:
main.h:
#include <stdlib.h> /* for size_t */
struct VLA_descriptor
{
void * p;
size_t s;
}
extern struct VLA_descriptor vla_descriptor;
foo.h:
void foo(void);
foo.c:
#include "main.h"
#include "foo.h
void foo(void)
{
char (*p)[vla_descriptor.s] = vla_descriptor.p;
/* Do something with the VLA reference p. */
}
main.c:
#include "main.h"
#include "foo.h"
struct VLA_descriptor vla_descriptor = {0};
int main(int argc, char ** argv)
{
size_t s = atoi(argv[1]);
char (*p)[s] = malloc(s);
vla_descriptor.p = p;
vla_descriptor.s = s;
foo();
... /* Free stuff and return. */
}
Error checking had been omitted in this example's code for the sake of readability.
With much thanks to #alk (and everyone else who responded) I think I have the closest I'm going to get to what I'm looking for:
void *LC
int LCS;
int main(int argc, char **argv) {
LCS=256;
LC=malloc(1024)
memcpy(((char(*)[LCS])LC)[2],"hello world",11);
((char(*)[LCS])LC)[0][176]=123;
printf("%d %s\n",((char(*)[LCS])LC)[0][176],&((char(*)[LCS])LC)[2]);
}
((char(*)[LCS])LC) is the equivalent of a what I wanted. It's similar to #alk's idea and does require 2 globals but it means I can use it in functions without having to declare a new variable. I've credited #alk with the answer as what he posted gave me 90% of what I needed.
Though if anyone can reduce ((char(*)[LCS])LC) to a single global, I would be excited to see it :)

usage of strdup

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s;
s = strdup("foo");
printf("%s\n", s);
getchar();
return 0;
}
Looks pretty harmless, doesn't it ?
But my IDE, which is Dev-C++, gives my the following warning:
warning: assignment makes pointer from integer without a cast
The warning disappears if you would change the code like this:
char *s;
s = (char*)strdup("foo");
Can anyone help me explain this?
You're using Dev-C++, but strdup is not part of the C or C++ standard, it's a POSIX function. You need to define the proper (according to your IDE's documentation) preprocessor symbols in order for strdup to be declared by the header file ... this is necessary in order for the header file not to pollute the name space when included into conforming C or C++ source files.
For a simple portable alternative, consider
char* mystrdup(const char* s)
{
char* p = malloc(strlen(s)+1);
if (p) strcpy(p, s);
return p;
}
Or, if you know strdup is actually in the library, you can copy its declaration from string.h into your own source file or header ... or use the simpler declaration from the man page:
char *strdup(const char *s);
That's not right. strdup returns char * already. Something else is wrong. Probably because you did not include the right header file that declares the true return type for this function.
#include <string.h>
You're missing #include <string.h>. In the absence of function signatures, strdup is assumed by the compiler to return an int, hence the warning.
man strdup
you will get following things
#include<string.h>
char* strdup(const char * s);
so strdup() returns char* there shuld not be any problem
Actually in your case it takes implicit declaration of strdup() so by default return type is int hence you get this warning
Either include<string.h>
or
give forward declaration char* strdup(const char *);
Also don't forget to free(s) in last when all usage are done

Resources