C puzzle: how will you print something on console? - c

/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
This was asked during an interview.
I was told to print something on console.
anybody?

Really surprised that nobody posted this yet:
#include <stdio.h>
#if 0
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
#endif
int main()
{
printf("Hello, World!");
return 0;
}
Prints at runtime and no undefined behavior whatsoever.

weird question...
int main(void)
{
printf("hello");
return 0;
}
#define main int lol
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/

#include <stdio.h>
#define exit(c) return puts("foobar"),0
over main

One implementation defined way would be to use the pragma directives to print during compilation.
#pragma message "Compiling " __FILE__ "..."
Or, you could do this with some macros and a printf (but not without introducing UB in some aspect or the other) at runtime.
#define exit(x) printf("Hello, world!")
int main() {
exit(0);
return 0; /* if pre-C99 */
}

#include <stdio.h>
#pragma message("Some foobar")
#error This is an error message
int main()
{
exit(0);
}
I think the interviewer wanted to know if you're aware of the #error directive ... just my 2 cents.

Most answers involve the #define c-preprocessor instruction to change what the program means. Most compilers also support something like
#pragma startup foo()
details depend on the compiler vendor. You can make code run BEFORE main(*) is called that way.

#define exit(x) (printf("Bye"))
int main(int argc,char* argv)
{
exit(0);
getchar();
return 0;
}

Solution 1.
This works without any preprocessor directives in cl and gcc, although I've not tested to make sure I'm not using any extensions:
#include <stdio.h>
static void exit() {
printf("Hello world");
}
/*you cannot change anything from here below*/
main()
{
exit(0);
}
/*you cannot change anything from here up*/
I think it's valid but I can't remember if masking a standard library function is allowed or not.
Solution 2
As several other answers have specified, you can use preprocessor directives, eg:
#define main or exit to be something that calls ifdef
use #if 0 to prevent the existing code being compiled
using #pragma message or #error to print a message at compile time
using #pragma startup to use a different function as main or to run start-up code before main.
Solution 3
If your compiler supports any C++ features in addition to C, there are many answers:
Declare a class with a constructor and a static variable of that type
Put the existing "main" function into a separate namespace (or class definition) and write a different global main
Solution 4
I also looked for any way of forcing a run-time error (stack overflow, out of memory, null dereference, tc), which would normally cause the program to print something, but couldn't find any way that didn't involve running extra code, in which case the extra code might as well be printf.

If you interpreted the question to mean you could not or were not allowed to edit the file by commenting out /* */ or using #ifdef _COMMENT_ME_OUT__ #endif respectively above and below the section you are not allowed to edit and then introducing a new main, then you should give an answer of using another .c file.

If you cannot find a workaround to edit that file, then use a different c file.

Related

When should I use preprocessor directives over if statements

I am sorry if this sounds like a dumb question, I am learning C, and I was wondering: when should I prioritize this syntax, for example
#include <stdio.h>
#define ALIVE 1
int main(void) {
#if ALIVE
printf("Alive");
#else
printf("Unalived");
#endif
}
Over this syntax (example):
#include <stdio.h>
#define ALIVE 1
int main(void) {
if (ALIVE)
printf("Alive");
else
printf("Unalived");
}
Thank you for spending time reading my question, I hope this isn't a dumb question and I wish you a nice day.
For starters, and to see the main difference between the two programs you show, let's see how they will look after preprocessing.
The first one:
#include <stdio.h>
#define ALIVE 1
int main(void) {
#if ALIVE
printf("Alive");
#else
printf("Unalived");
#endif
}
will expand to
#include <stdio.h>
int main(void) {
printf("Alive");
}
The second one:
#include <stdio.h>
#define ALIVE 1
int main(void) {
if (ALIVE)
printf("Alive");
else
printf("Unalived");
}
will expand to:
#include <stdio.h>
int main(void) {
if (1)
printf("Alive");
else
printf("Unalived");
}
[Examples above skip the actual inclusion of the header file]
While this doesn't directly answer your question it can give hints to what using the preprocessor conditional compilation for.
The main use is to conditionally give the compiler different code depending on the macros. Mostly used for portability-issues, when creating programs that needs to be built for different systems (for example Linux and Windows).
When using the preprocessor to do conditional compilation, whole parts of the code, that would otherwise be invalid on the target system, could simply be omitted and the compiler won't even see it.
If you use the standard C if statement, then both branches of the condition must be valid code that the compiler can build.
As a rule of thumb, you should always prefer if (... over #if and should only use #if where if will not work
when there's something in the if that is syntactically incorrect when the condition is false so it won't compile at all
when you need to do this at the global scope, where statements (like if) are not allowed
in your example, the if version is much better.

C header file is causing warning "ISO C requires a translation unit to contain at least one declaration"

Using Qt Creator I made these plain C files just to test my understanding:
main.c
#include <stdio.h>
#include "linked.h"
int main()
{
printf("Hello World!\n");
printf("%d", linked());
return 0;
}
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
linked.c
int linked()
{
return 5;
}
The IDE shows a warning on the line of linked.h in-between #define LINKED_H_ and int linked(void); which reads
ISO C requires a translation unit to contain at least one declaration
My best guess about what this means is that any header or other C file, if it is in a project, should get used in the main file at least once somewhere. I've tried searching the warning but if this has been answered elsewhere, I'm not able to understand the answer. It seems to me I've used the linked function and so it shouldn't give me this warning. Can anyone explain what's going on?
The program compiles and runs exactly as expected.
I think the issue is that you don't #include "linked.h" from linked.c. The current linked.c file doesn't have any declarations; it only has one function definition.
To fix this, add this line to linked.c:
#include "linked.h"
I don't know why it says this is an issue with linked.h, but it seems to be quite a coincidence that the line number you pointed out just happens to be the line number of the end of linked.c.
Of course, that may be all this is; a coincidence. So, if that doesn't work, try putting some sort of external declaration in this file. The easiest way to do that is to include a standard header, such as stdio.h. I would still advise you to #include "linked.h" from inside linked.c, though.
add a header
#ifndef LINKED_H_
#define LINKED_H_
#include <stdio.h>
int linked(void);
#endif // LINKED_H
The way you wrote the code, you need to use:
extern int linked(void);
(notice the additional "extern"). That might help with the issue.
Also, the code in linked.c should be:
int linked(void)
{
return 5;
}
(Notice the "parameter" - "void").
According to IBM, you need some declaration in the header file, but you do have one. Perhaps LINKED_H_ is defined elsewhere, or the compiler is seeing that it's possible that the precompiler condition might result in an empty parse.
Perhaps this header file will work for you:
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
char __allowLinkedHToBeIsoCCompliant = 1;

Show error on using preprocessor before the main function

#include <stdio.h>
#define A 1
#if A
printf("Csau");
#endif
int main()
{
return 0;
}
I am trying to run this but my compiler is giving me the error of
main.c:4:9: error: expected declaration specifiers or '...' before
string constant printf("Csau");
Any suggestions why this isn't working ?
P.S. In main function it's working fine with some minor modification.
Edit : Anyway I can show the output outside the main function ?
You can output messages at compile time:
#include <stdio.h>
#define A 1
#if A
#warning "Csau"
#endif
int main()
{
return 0;
}
At runtime you can not print something outside another function body.
Once preprocessed, your code boils down more or less to this:
#include <stdio.h>
printf("Csau");
int main()
{
return 0;
}
And this is not correct C. You cannot call a function outside functions. It doesn't make sense. When you run the program, the system calls your main function and that's it.
You are getting this error because you are trying to call printf from outside of main (or outside of another function)
Edit : Anyway I can show the output outside the main function ?
No. The program starts at the beginning of the "main" function. Putting code outside of functions is syntactically incorrect. Even if the compiler let you do it, the code would never be executed.
The preprocessor doesn't run before main() (aka: before execution) but before compilation. The actual compilation step is fed the results of preprocessing as input, so, in your case, an invalid C program, as you can't have statements outside of functions.
At runtime of your program, there is nothing before entering main(). Of course, your runtime will probably setup a few things, but anything happening before main() is called is not part of your C program.

Stripping specific functions on compile time

I'm writing a C program that uses a custom logging function to debug my program. Whenever I compile my program as a release version, I want all of my logging functions to be stripped from the code so it won't show up if someone tries to disassemble it.
Take the following example:
#include <stdio.h>
void custom_logging_function(char* message)
{
// Do something here
}
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
How could I make it so that the custom_logging_function and it's arguments aren't compiled into my program without having to write include guards everywhere throughout my code? Thank you
You can use pre-processor flags, for example:
#include <stdio.h>
#ifdef DEBUG
void custom_logging_function(char* message)
{
// Do something here
}
#else
#define custom_logging_function(x) ((void) 0)
#endif
int main()
{
custom_logging_function("Hello world"); // This call should be removed.
return 0;
}
With this code you will have to tell the "debug" target to define DEBUG, if you want to define something specifically for the "release" target you can replace #ifdef DEBUG with #ifndef NDEBUG and add the NDEBUG flag to the "release" definitions.
Edit:
Changed #define custom_logging_function(x) 0 to #define custom_logging_function(x) ((void) 0) inspired by #JoachimPileborg his answer.
Assuming you only want the logging calls to happen in a debug-build of your application, and not the release build you send to customers, you can still use the preprocessor and conditional compilation for it. It can be made vert simple though by using macros instead of having checks at every call.
Something like this in a heder file:
#ifdef _DEBUG
void custom_logging_function(char* message);
#else
# define custom_logging_function(message) ((void) 0)
#endif
You could use an empty macro body for the release-macro, but that can cause some compilers to give "empty statement" warnings. Instead I use an expression casted to void (to tell the compiler that the result of the expression will not be used). Any smart compiler will not include the expression after optimization.

Sleep | warning implicit declaration of function `sleep'?

I am learning C.
In this program
I use sleep function to slowdown a count down.
My text book doesn't specify a library I should include to use the sleep function.
So I use it without including any special library for it and it works.
But it gives me this warning message in codeblocks.
I tried to include <windows.h> but still the same warning message appears.
warning D:\Project\C language\trial8\trial8.c|19|warning: implicit
declaration of function `sleep'|
And here is my code.
#include <stdio.h>
int main()
{
int start;
do
{
printf("Please enter the number to start\n");
printf("the countdown (1 to 100):");
scanf("%d",&start);
}
while(start<1 || start>100);
do
{
printf("T-minus %d\n",start);
start--;
sleep(3000);
}
while(start>0);
printf("Zero!\n Go!\n");
return(0);
}
I want to know what does the warning message mean? How important is it? Is there anything that I should do about it? Note that the program works anyway.
The issue is in the libraries (header files):
on Windows:
#include <windows.h> and Sleep(1000); => 1000 milliseconds
on Linux:
#include <unistd.h> and sleep(1); => 1 second
The function sleep is not part of C programming language. So, C compiler needs a declaration/prototype of it so that it can get to know about about number of arguments and their data types and return data type of the function. When it doesn't find it, it creates an Implicit Declaration of that function.
In Linux, sleep has a prototype in <unistd.h> and in windows, there is another function Sleep which has a prototype in <windows.h> or <synchapi.h>.
You can always get away with including header, if you explicitly supply the prototype of the function before using it. It is useful when you need only few functions from a header file.
The prototype of Sleep function in C on windows is:
VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
Remember, it is always a good practice to supply the prototype of the function being used either by including the appropriate header file or by explicitly writing it. Even, if you don't supply it, compiler will just throw a warning most of the time and it will make an assumption which in most cases will be something that you don't want. It is better to include the header file as API might change in future versions of the Library.
Windows doesn't have the sleep function. Instead, it has Sleep, which takes the number of milliseconds to sleep:
VOID WINAPI Sleep(
_In_ DWORD dwMilliseconds
);
You'll need to either #include <windows.h> or #include <synchapi.h>, depending on the version of Windows you're running. See MSDN for more details.
Update in 2022:
As it is stated on the Linux man page here we need to include unistd.h and should do fine for all OS.
#include <stdio.h>
#include <unistd.h>
int main()
{
sleep(1); /* sleep for 1 second*/
printf("END\n");
return 0;
}
To make it more cross-platform, try this:
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

Resources