I'm using codeblocks to learn C programming.
When I use /* */ the program works, but when I use // the program returns this error.
expected identifier or ‘(’ before ‘/’ token|
here's the main.c
#include <stdio.h>
#include <stdlib.h>
//Ex1
int i;
float p;
char *n;
int main(void)
{
i = 22;
p = 70.0;
n = "Samuel";
printf("%s %d %.2f", n, i, p);
return 0;
}
From wiki:
C++ style line comments start with // and extend to the end of the line. This style of comment originated in BCPL and became valid C syntax in C99; it is not available in the original K&R C nor in ANSI C:
If you use gcc compiler, then add -std=c99 compiler argument.
It will enables C99 features, like // comments.
If you have -ansi option, then remove it.
Four major versions of the C language exist:
ISO 9899:2011. The current standard, known as C11. Allows //.
ISO 9899:1999. An obsolete standard, known as C99. Allows //.
ISO 9899:1990. An obsolete standard, known as C90, or sometimes C89. Does not allow //.
Pre-standardization. Known as "K&R C". Does not allow //.
Make sure to use a modern compiler with support for the relevant standard. Today, you should demand that a C compiler at least conforms with C99.
Related
I have the following program:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *tp = NULL, *cp = NULL, *next_token = NULL;
char TokenListe[] = "Hello,I Am,1";
tp = strtok_s(TokenListe, ", ", &next_token);
printf(tp);
return 0;
}
When I compile it with Visual Studio 2015 it compiles, without any warning.
But when I compile it with Dev C++ 5.11 I get the following warning in line 10:
[Warning] assignment makes pointer from integer without a cast
Is there any solution to fix that warning?
Since C11, strtok_s is now standard C, part of the optional "bounds-checking interface" (Annex K). Compilers need not support it.
But if they do, the format is this (C11 K.3.7.3.1):
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
char *strtok_s(char * restrict s1,
rsize_t * restrict s1max,
const char * restrict s2,
char ** restrict ptr);
Any other format is non-standard garbage and should not be used, including Microsoft strtok_s.
Dev C++ is no longer maintained and therefore only contains a very old version of gcc. It does not support C11, but to my knowledge, no newer version of gcc + libraries yet support the C11 bounds-checking interface either. Visual Studio is a non-conforming compiler and can't be used for compiling standard C. Generally, I would advise to use neither of these compilers, but to update to a new version of gcc (for example Codeblocks with Mingw).
Summary: strtok_s cannot be used in sensible ways. Use strtok instead. Simply ensure that all buffers involved are large enough and can't be overrun. In case of a multi-threaded program, simply don't use strtok at all.
If Dev C++ doesn't have the non-standard strtok_s, in C it will be implicitly declared, and assumed to return integer.
Note: strtok_s is in the standard, but as an "optional extension", according to (my free draft copy of the) C11 standard.
You should enable other warnings too, such as the warning for implicit declarations of functions.
If Dev C++ does contain an implementation of strtok_s, and links with it, declaring it yourself might work. But a better option is to find the right header file, or compiler flags, to get it declared, if any such options exist. Consult the documentation.
But note, as Michael Walz commented, that the strtok_s in the C11 standard and Microsoft's strtok_s are different, and don't have the same parameters! I don't know which version Dev C++ implements.
Based on the answer from #thomas-padron-mccarthy, I could fix my problem with declaring the strtok_s function in my header file.
extern char* strtok_s(char*, char*, char**);
#include<stdio.h>
void fun(z)
{
printf("%d",z);
}
int main()
{
int a=5;
fun(a);
}
This is giving output as 5. Shouldn't it give an error - undeclared variable z ?
Is this a compiler optimization ?
This is not a compiler optimization, it is a compliance with an ancient C convention that allowed you to skip variable and parameter types when the desired type is int. This convention pre-dates the ANSI standard, and should be avoided even if your compiler is fine with such code.
You will get a warning if you tell the compiler that you want your code to comply with one of more modern standards, say, C99 or C11. The flag is compiler-dependent. If you are using gcc, add
-std=c99
flag to see the warning.
int h, i;
void B(int w) {
int j, k;
i = 2 * w;
w = w + 1;
...
}
void A(int x, int y) {
float i, j;
B(h);
i = 3;
...
}
int main() {
int a, b;
h = 5; a = 3; b = 2;
A(a, b);
B(h);
return 0;
}
As far as the modern compilers are concerned, I find that function A() is not allowed to call function B(). I find the same with compiler like gcc and turboc.
I have heard from my Prof. that standard C allows B() to call A() and vice-versa, with the same code. Is it true?
Where can I find more info regarding actual concepts of standard C?
(Posting this answer as there are many misconceptions in the main comments):
In all versions of Standard C, A can call B, and B can call A
A prototype is not required in any version of Standard C. (But it is a good idea to use one anyway as they help the compiler to diagnose errors).
In ISO C99 and ISO C11, a function declaration must be visible of the function being called.
In ISO C90, it is possible to call a function without a visible declaration. This call runs correctly if all of the following conditions are met (otherwise the behaviour is undefined):
The function definition returns int (or omits the return type)
The function definition is not variadic
The ordered list of types of the arguments, after the default argument promotions are applied, matches exactly the ordered list of types of the parameters to the function definition (the parameter types are not promoted).
For example, in all versions of Standard C, the ... in the OP code inside B() may be replaced with:
void A();
A(w, i);
making a correct program. In ISO C90, the ... may be replaced with simply:
A(w, i);
The standards makes this legal in order to avoid breaking existing code which was written before prototypes were invented. It would be embarrassing if the code in K&R1 stopped working in Standard C.
I repeat that it is not a good idea to do this on purpose if you are writing new code; it's better to put a prototype, and the best position for the prototype is outside of the function.
You can download drafts of the ISO C11 standard, and the ISO C99+TC3 standard here. AFAIK there is no free and legal copy of the C90 or original C99 text. The cheapest legal way to get the C90 text is to buy the book The Annotated C Standard. This is cheaper than buying it from ISO, although it is said that the price difference represents the added value of the annotations.
There are many second-hand sources of information about Standard C, e.g. questions on this site which are tagged c.
I was trying to do this in ANSI C:
include <stdio.h>
int main()
{
printf("%d", 22);
int j = 0;
return 0;
}
This does not work in Microsoft Visual C++ 2010 (in an ANSI C project). You get an error:
error C2143: syntax error : missing ';' before 'type'
This does work:
include <stdio.h>
int main()
{
int j = 0;
printf("%d", 22);
return 0;
}
Now I read at many places that you have to declare variables in the beginning of the code block the variables exist in. Is this generally true for ANSI C89?
I found a lot of forums where people give this advice, but I did not see it written in any 'official' source like the GNU C manual.
ANSI C89 requires variables to be declared at the beginning of a scope. This gets relaxed in C99.
This is clear with gcc when you use the -pedantic flag, which enforces the standard rules more closely (since it defaults to C89 mode).
Note though, that this is valid C89 code:
include <stdio.h>
int main()
{
int i = 22;
printf("%d\n", i);
{
int j = 42;
printf("%d\n", j);
}
return 0;
}
But use of braces to denote a scope (and thus the lifetime of the variables in that scope) doesn't seem to be particularly popular, thus C99 ... etc.
Now I read at many places that you have to declare variables in the beginning of the code block the variables exist in. Is this generally true for ANSI C 89?
Yes, this is required in the syntax of a compound statement in the C89/C90 Standard:
(C90, 6.6.2 Compound statement, or block)
Syntax
compound-statement
{ declaration-list_opt statement-list_opt }
Declaration have to be before statements in a block.
C99 relaxed this by allowing mixing of declarations and statements in a block. In the C99 Standard:
(C99, 6.8.2 Compound statement)
Syntax
compound-statement:
{ block-item-list_opt }
block-item-list:
block-item
block-item-list block-item
block-item:
declaration
statement
This is absolutely true for C89. (You're better off looking at documentation for the language, e.g., books and standards. Compiler documentation usually only documents differences between the language the compiler supports and ANSI C.)
However, many "C89" compilers allow you to put variable declarations nearly anywhere in a block, unless the compiler is put in a strict mode. This includes GCC, which can be put into a strict mode with -pedantic. Clang defaults to a C99 target, so -pedantic won't affect whether you can mix variable declarations with code.
MSVC has rather poor support for C, I'm afraid. It only supports C89 (old!) with a few extensions.
I've read that C89 does not support variable-length arrays, but the following experiment seems to disprove that:
#include <stdio.h>
int main()
{
int x;
printf("Enter a number: ");
scanf("%d", &x);
int a[x];
a[0] = 1;
// ...
return 0;
}
When I compile as such (assuming filename is va_test.c):
gcc va_test.c -std=c89 -o va_test
It works...
What am I missing? :-)
GCC always supported variable length arrays AFAIK. Setting -std to C89 doesn't turn off GCC extensions ...
Edit: In fact if you check here:
http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options
Under -std= you will find the following:
ISO C90 programs (certain GNU
extensions that conflict with ISO C90
are disabled). Same as -ansi for C
code.
Pay close attention to the word "certain".
C89 does not recognize // comments.
C89 does not allow definitions intermixed with code.
You need to fflush(stdout) after the printf to be sure of seing the prompt before the scanf.
main "looks better" as int main(void)
Try gcc -std=c89 -pedantic ... instead
You're missing that without -pedantic, gcc isn't (and doesn't claim to be) a standard-conforming C compiler. Instead, it compiles a GNU dialect of C, which includes various extensions.