Quantcast Job Interview Questions - www.interviewhelper.org: December 2007



Get unlimited interview questions on our new improved website...


 Interview Helper Home | Forum | Submit Link | Online Tickets | Freelance Work | Free Games | Jobs

Thursday, December 20, 2007

H1 B Visa Interview Questions

Here we is a set of U.S. visa interview questions that you may be asked as a part of the H-1B visa application process.

  • What is the purpose of your trip to the United States?
  • Why do you want to work in the US?
  • Where are you working currently?
  • What is the company you are going to work in USA?
  • What is your role in US Company?
  • What is your current salary?
  • What is the salary you will get in United States?
  • Have you been to any other country before? If yes, how long was your stay there?
  • Where will you be staying in the U.S.?
  • How long do you plan to stay in the U.S.?
  • Will you be back to your home country?
  • When you will be back to your home country?

Points to Remember:

  • Applicants should practice for the interview with friends.
  • Applicant must arrive at the exact time mentioned in the appointment letter.
  • Applicant must answer all questions clearly during the interview.
  • Applicant must be honest with consular officials at all times.
  • Applicants must ensure that they have all the forms and personal documents that they need to submit at the time of interview.

Some more questions

  1. What is the purpose of your trip to the United States?
  2. Do you have any family in the United States?
  3. Why are you changing your Job?
  4. Why do you want to work in the US?
  5. Have you applied for visa for any other country?
  6. Do you know what is the living cost in the U.S. specific to the place where you are going?
  7. When are you planning to travel?
  8. How will you survive for the first month?
  9. Have you been to any other country before?
    If yes, how long was your stay there?
  10. Will you come back to India?
  11. When will you return to india?
  12. Why would you want to return to India?
  13. Is it your first H1B or visa revalidation?
  14. After the conclusion of your visa, what will you do?

Questions About Your Education/Experience

  1. Are you a student?
  2. Which university is your degree from?
  3. What was your thesis about?
  4. What is the diff between PL SQL n SQL?
  5. What are the software’s you know?
    Do you have work experience with them?
  6. What courses did you complete here [Home Country]?
  7. Show me your certificates.
  8. Can I see your educational certificates and experience letters.
  9. Tell me in detail about all the jobs and work experiences and profile.
  10. What’s your highest educational qualification?

Questions About Your Current Company

  1. How long have you been working?
  2. Where are you working currently?
  3. What is your current salary?
  4. What is your current role in the current company?
  5. Is it an Indian company you currently work for?

Questions About Sponsoring Company

  1. What is the company you are going to work for in USA?
  2. Where are you going to work in US?
  3. Why are you joining [New Company]?
  4. How do you know this is a real company?
  5. When did you receive your offer letter?
  6. What will you be working on there? Is it an internal project?
  7. I need a client letter describing your work project.
  8. Tell me what do you know about [New Company]?
  9. When was the US company founded?
  10. Tell me about the project and the company (client) you will be working for?
  11. How did you find out about this company?
  12. How did you contact the [New Company]?
  13. What is the current project you will be working on?
  14. What are your responsibilities and for which client are you going to be working for? Please explain in detail.
  15. Do you have any proof from your new employer regarding your responsibilities?
  16. Do you have any company photographs?
  17. How long has the company been in the current location?
  18. How many rounds of interviews has the USA company conducted?
    What are they?
  19. What is the name of your interviewer?
  20. Can you give me the dates of your interview?
  21. Who are the clients for your U.S. company?
  22. What are the technologies you are working on?
  23. Who is the President/CEO of the U.S. company?
  24. What kind of projects is the U.S. company working on?
  25. What is the annual turn over of the company?
  26. How many employees does the U.S. Company have?
  27. What’s your designation in [Previous Company] and what's your designation in the [New Company]?
  28. Will you be working from [New Company] office or client's place?
  29. Can I see the Employee petition to USCIS and the Tax Returns of the Company?
  30. What is the salary you will get in USA?
  31. How many rounds of interviews did the U.S. company conduct?
    What are they? 4 rounds (2 technical, 1 HR, 1 manager interview)
  32. Can I see your client end letter and itinerary of services.

A few more here

1)How you came to know about this company?
2)Where are you working currently?
3)What is the company you are going to work in USA?
4)What is your current salary?
5)What is the salary you will get in USA?
6)How many rounds of interviews the USA company conducted? What are they?
7)Who had taken interview for you?
8)Can you give me the dates of your interview?
9)Who are the clients for your USA company?
10)What are the technologies you are working on?
11)Who is the President/CEO of US company?
12)What kind of projects US company is working on?
13)What is the annual turn over of the company?
14)How many employees in US Company?
15)Why are you changing your Job?
16)Why you want to work in US?
17)Have you applied for any other Country?
18)Do you know what is the leaving cost in US specific to the place where you are going?
19)When did you received your offer letter?
20)What is the current project you are going to work?
21)What is your current role?
22)What is your role in US company?
23)Where are you going to work in US?
24)What is your designation in US company?
25)When did US company founded?
26)What is your current pay?
27)What is your pay in US company?
28)When are you planned to travel?
29)How will you survive for the first month?
30)Have you been to any other country before?
31)Will you come back to India?
32)When you will be back to india?
33)Why you want to return back?

AS/400 Interview questions

How do I trim leading zeroes?

Is there a BIF to trim leading 0's off of a numeric field AND reduce the field size accordingly?

 i.e. a field with a value of 000012345
I want to print:
"value: 12345" instead of
"value: 000012345" or
"value: 12345"

Use a combination of %edit and %trim. The %edit BIF will edit your number any way you wish: suppress leading zeroes, add commas, etc. The %trim BIF will strip the blanks off the front. Typical use for this is to insert a numeric amount into a message, like "Your balance is $25.00" Here is some code to do that: EDITBIF RPG IV 9 Mar 2001


%size gives me a compile time error on my D specs

%size doesn't accept an expression; try %len instead.


%trim is very slow

I did a quickie test of this on my heavily loaded 620. 5000 loops of %trim(String). "String" contains the literal "A":

If "String" is declared 20 bytes long, it takes :01.
If "String" is declared 32000 bytes long, it takes 1:45
If "String" is declared 20 bytes varying, :01.
If "String" is declared 32767 bytes varying, :01.

The moral of the story: try variable length fields for your string manipulation chores.


How can I right justify a field?

For V4R4 and above:
c evalr output = %trimr(input)
For earlier releases:
c Eval output =
%subst(BLANKS:1:%len(input) -
%len(%trimr(input))) +
input

where "input" and "BLANKS" are equal length character fields.


How can I centre a field?

Basically, take half the length of the output field, subtract half the length of the trimmed input field, put that many blanks at the front of the output field and add the input field. Watch out for output size less than input size and blank input!

d input           s             24    inz('1234567890              ')
d output s 40 inz
d BLANKS s like(output) inz
d len s 10i 0

c eval len = (%len(output)/2) -
c %len(%trimr(input))/2

c if len + %len(%trimr(input)) <= c %len(output) c eval output = %subst(BLANKS: 1: len) + c input c else c eval output = input c endif

Does %len count the null in a null terminated string?

The quick answer is no. Hans Boldt supplied this amplification:

Well, I don't mean to nitpick, but there are no null characters in the field after the %trim. "C" convention uses the null character to indicate the end of a character string. But in RPG IV, we maintain a separate length attribute. For char varying fields, the length is a 16-bit unsigned number at the beginning of the fields storage. (Within expressions, though, the length is held in some temporary variable.) Within a char varying field, the characters following the logical end of the data can be anything, but they're ignored by RPG.

In order to support the character string BIF's, we actually had support for the character varying type within expressions since V3R1. However, we didn't get around to actually adding the varying data types until V4R2. Priorities, you know. If you need to pass a null terminated string to a "C" function, use keyword OPTIONS(*STRING). Or to use a null terminated string as a normal RPG IV char field, use built-in function %STR.

Answer courtesy Hans Boldt via MIDRANGE-L


Date/time datatypes


I get RNX0112 when I use L (date) data types in my display file.

If you use CAnn instead of CFnn, this will happen because of the way the I/O buffer is validity checked by the RPG runtime. Internal to work station data management (WSDM), there is a working buffer (WB) which contains the current values for all fields on the display station (actually there is one WB per active record format on the display). When the user uses a CF key/ENTER/etc. the current display values are moved to this WB and verified.

If one or more errors are encountered (VALUES, RANGE, Date validation, etc.) then WSDM responds with an error message. When no errors are encountered, WSDM moves the WB contents to the input buffer associated with the *DSPF and RPG application, and returns control to the RPG program (or RPG runtime anyway).

What is happening is that the ENTER key is causing the invalid date to be loaded into the WB, the error is being reported, the CA key is being used to bypass entry, and the WB (in it's last used invalid state) is being returned to the RPG program. RPG runtime appears to be validating the Date field contents and is signalling the RNX0112.

Note that the very same thing (except for the RNX0112) occurs with VALUE DDS checking. If a VALUES('A' 'B' 'C') is defined and the user enters "E", ENTER, CA then the RPG program does indeed get 'E' returned (but as there is no datatype error you don't get an explicit error message).

This situation is documented in the DDS manual under CAnn as part of Validity Checking Considerations with suggested workarounds of:

  1. Don't use CA keys or
  2. Don't use functions such as VALUES, RANGE, CHECK(VN), etc.
As Date validity checking is done in the same manner as these other DDS keywords (that is, in WSDM and not the work station controller) it falls into the same classification.

Error handling


I'm using the *PSSR and want to return to the line of code following the one in error. How do I do that?

You can't directly GOTO the line after the error occurred. Basically, you'll need to set a flag to indicate where you are, then your *PSSR does an ENDSR *DETC. Now that you're at the top of the detail calcs, you check your flag and GOTO the spot after the error, something like this, perhaps: Demonstrate *PSSR 16 Mar 2001


APIs


Can I use RPG to read and write to the IFS?

Scott Klement donated these code samples in a post on MIDRANGE-L:

  • IFS prototype header /COPY
  • IFS API examples

What does BINARY 4 mean?

Several IBM API documents refer to "binary 4." What exactly does that mean?

BINARY(4) means a 4-byte binary number.

  • In RPG III, this means a subfield of a data structure that is defined with 4 bytes, and has the 'B' type.
  • In RPG IV, there are two kinds of 4-byte binary number: the 10-digit integer or the 9-digit binary. The 10-digit integer is better when dealing with APIs. If you define an integer or binary number using length notation (no from-position), you give the number of digits. 10I-0 or 9B-0. A very common error is to define a BINARY(4) field or parameter using length notation as 4B-0. This always causes problems calling the API.

Answer courtesy Barbara Morris 15 Mar 2001


How can I get a list of jobs for a user?

Mark Walter provides an RPG program that uses the following APIs:

  • QUSCRTUS - Create user space
  • QUSLJOB -- List user jobs into user space
  • QUSRTVUS - Retrieve data from user space
  • QCMDEXEC - Execute OS/400 command
  • QUSDLTUS - Delete user space

The program gets a list of jobs for the current user at status *JOBQ and puts the list in a user space. It then builds an array of jobs that can be readily manipulated. This example performs an ENDJOB command on each one.

Answer courtesy Mark Walter via MIDRANGE-L 5 Feb 2001


Indicators


How can I position the cursor in a display file without using up an indicator?

I got this from MIDRANGE-L long ago and foolishly neglected to keep track of the kind soul who posted it. Use the CSRLOC DDS keyword, and you can position exactly by row and column. Here are DDS and RPG IVexamples.

Answer courtesy MIDRANGE-L 16 Apr 2001


How can I highlight a field in a display file without using up an indicator?

Use DSPATR with a program to system field. Here are DDS and RPG IVexamples. You can't set Position Cursor, unfortunately.

Answer courtesy Dave Mahadevan via MIDRANGE-L 16 Apr 2001


Debugging


How can I debug ILE programs?

Brad Stone has a FAQ entry that addresses this.

If that site is unavailable, here is a list of steps culled from posts to RPG400-L:

    Using the green screen debugger:
  1. Submit your program to batch. The job MUST be held. You can either hold the job queue (HLDJOBQ) or hold the individual job (HLDJOB) or specify HOLD(*YES) on the SBMJOB command.
  2. WRKSBMJOB/WRKUSRJOB/WRKACTJOB and find your submitted job. Note that the SBMJOB command gives you an informational message with the job name/number. What you need is the job name, user ID and job number - the fully qualified job name. Example: 123456/BUCK/MONTHEND
  3. STRSRVJOB on the held batch job.
  4. STRDBG on your program. Specify UPDPROD(*YES) if needed. You'll see the source listing if you compiled with DBGVIEW(*LIST) or *SOURCE.
  5. Press F12 to exit - you cannot set a breakpoint yet.
  6. Release the job so that it becomes STATUS(*ACTIVE).
  7. You'll see a display asking if you want to debug or continue. Press F10 to debug.
  8. DSPMODSRC to see the source listing again. Alternately, press F10 to step into the first instruction.
  9. Now you can add your breakpoints.
  10. Press F3 until you're back to the "debug or continue" display. Press Enter to run the program with your breakpoints set.
  11. When you're done, do an ENDDBG and ENDSRVJOB.

Thanks to Bob Slaney, Phil, Patrick Conner and Kelly Fucile.

    Using the IBM Distributed Debugger:
  1. SBMJOB CMD(CALL PGM(yourlib/yourpgm)) JOBQ(yourlib/yourjobq) HOLD(*YES)
  2. Start your Code debugger from Start->Programs->WebSphere Development...->IBM Distributed Debugger->IBM Distributed Debugger
  3. Select the debugger Start up window and key into the job name entry field */##########/* where ########## is your user id.
  4. You may have to log in and specify the AS/400 system name.
  5. Select the job that is being held in yourjobq.
  6. Click the ok push button.
  7. Enter the library and program name into the Program entry field
  8. Click the Load push button on the debugger Startup information window. A debugger message will appear telling you to start the program.
  9. Click Ok on the message push button, even though it tells you to start your program first.
  10. Switch to a 5250 emulation window.
  11. WRKJOBQ JOBQ(yourlib/yourjobq)
  12. Release your job.

Answer courtesy Rob Berendt via RPG400-L 2 Aug 2001


How can I debug OPM programs?

If you're willing to use the old OPM debugger, you can use the ILE steps outlined above.

Mike Barton suggests compiling the program with OPTION(*SRCDEBUG) and then using STRDBG OPMSRC(*YES), which should work with the steps given above.

STRISDB won't work unless the job is running, so you can't put it on hold and enter your break points.

Martin Rowe contributed the following idea: Insert a simple CL program into your RPG that waits for you to answer a message. This way, the job is running, but not processing yet. (RPG400-L 24 May 2001)

Here is an adaptation of his idea:

Here's the RPG program you're trying to debug:
H 1
C CALL 'DBGWAIT'
C Z-ADD1 X 50
C SETON LR

I've inserted "CALL 'DBGWAIT'" and re-compiled.

Here's the source for DBGWAIT:
pgm

dcl &reply *char 1

sndusrmsg msgid(CPF9898) +
msgf(QCPFMSG) +
msgdta('Paused for debug') +
msgrpy(&reply)

endpgm

And here are the actual debugging steps:

  • STRISDB PGM(BATCHOPM) UPDPROD(*NO) INVPGM(*NO) SRVJOB(*SELECT) You'll see a list of all active jobs on your system.
  • Select the one you're trying to debug. You'll get a message saying that the program is in debug mode.
  • Answer the "paused for debug" message, and the source will pop up after the call to DBGWAIT.

The Rest (not easily catalogued)


Why is garbage in my *ENTRY parameters?

This is undoubtedly a result of a mis-match between the definition of the parameters between the caller and the called program. Very often, this mis-match is unwittingly caused by calling a program from a command line (or SBMJOB).

The following text uses CL as an example, but the same ideas work for RPG as well. CL is used, because it is usually a CL command (SBMJOB or CALL) that reveals the mis-match. Text by John Taylor

CL Parameter Basics

When a variable is declared within a CL program, the system assigns storage for that variable within the program automatic storage area (PASA). If you subsequently use the variable as a parameter within a CALL command, the system does not pass the value of that variable to the called program, but rather a pointer to the PASA of the calling program. This is known as parameter passing by reference.

For this reason, it is very important that both programs declare the parameter to be of the same type and size. To illustrate, let's look at the following example:

PgmA: Pgm

DCL &Var1 *CHAR 2 Inz( 'AB' )
DCL &Var2 *CHAR 2 Inz( 'YZ' )

Call PgmB Parm( &Var1 &Var2)

EndPgm
PgmB: Pgm Parm( &i_Var1 &i_Var2 )

DCL &i_Var1 *CHAR 4
DCL &i_Var2 *CHAR 2

EndPgm

Hopefully, you've noticed that the first parameter is declared to be larger in PgmB than it was in PgmA. Although you might expect &i_Var1 to contain 'AB ' after the call, the following is what the input parameters in PgmB actually contain:

&i_Var1 = 'ABYZ'
&i_Var2 = 'YZ'

&i_Var1 shows the contents of the first parameter, and the second, because the second parameter is immediately adjacent to the first within the storage area. If the second parameter was not contiguous to the first, then the last two bytes of &i_Var1 would show whatever happened to be in the storage area at that time.

You can think of &i_Var1 as a 4-byte "window" into the storage area of the calling program. It's passed a pointer that tells it where the view begins, and it accesses anything in storage from that point up to the parameter's declared length.

Looking at Literals

There are several ways that a program can be called, other than from another program. Examples include the command line, SBMJOB, job scheduler etc. In the case of an interactive call from the command line, you specify the parameters as literals, ie:

Call PgmB Parm('AB' 'YZ')

Consider that when we do this, there is no PASA. We'll look at the implications of that in a minute, but for now, just make a note of it.

Submitting a job from the command line isn't any different. If you're submitting a CALL, then you'll be specifying any associated parameters as literals. However, things can get a bit deceiving when you submit a job from within a program, as the following example illustrates:

PgmC: Pgm

DCL &Var1 *CHAR 2 Inz( 'AB' )
DCL &Var2 *CHAR 2 Inz( 'YZ' )

SbmJob Cmd(Call PgmB Parm( &Var1&Var2))

EndPgm

Clearly, we're not passing literals here. Or are we?

Let's think about how things would work if we passed variables:

  • PgmC submits a call to PgmB, passing two variables as parameters.
  • PgmC immediately ends as a result of the EndPgm statement.
  • PgmB begins running in batch and receives pointers to PgmC's PASA.
  • PgmB crashes when it attempts to use the pointers.

We have invalid pointers because PgmC is no longer running. If you've ever tried this personally, you know that it doesn't happen in practice. The reason for that is that the system is converting those variables to literals before issuing the CALL command. Very sneaky, but effective.

Now that we've seen some examples of where literals are used, and why, it's time to talk about the PASA again. When we discussed the basics of CL parameter passing, we learned that the called program expects to receive a pointer to a storage area within the PASA for each input parameter. This requirement hasn't changed. So now we have a situation where the CALL command is passing literals, but the called program is still expecting pointers.

Obviously, it's time for the system to perform some more magic behind the scenes. In order to accomodate the requirements of the called program, the system creates a space in temporary storage for each literal being passed, and moves the value of the literal into that storage space. Now it can pass pointers to the called program, and everyone is happy.

Except you that is, because none of this changes the fact that you're getting "garbage" in the input variables of your called program! Fair enough. I'm getting to that now, but you needed the background in order to understand the next part.

Sizing It All Up

Now that you know the system is creating variables behind the scene, you might wonder how it knows what size those variables need to be. The answer is that it doesn't. Instead, the designers have imposed some specific rules about how literals are transformed to variables, and thereby passed as parameters.

CL supports only three basic data types: character, decimal, and logical. For the purposes of this discussion, you can consider the logical data type equivalent to the character type, because it's treated in the same manner.

The simplest rule is the one that handles decimal literals. All decimal literals will be converted to packed decimal format with a length of (15 5), where the value is 15 digits long, of which 5 digits are decimal places. Therefore, any program that you expect to call from the command line, or SBMJOB etc., needs to declare it's numeric input parameters as *DEC(15 5).

Character literals are a little bit more complicated, but still fairly straightforward. There are two rules to remember. The first is that any character literal up to 32 characters in length will be converted to a 32 byte variable. The value is left justified, and padded on the right with blanks.

So if you were to pass the following literal:

Call PgmB 'AB'

the associated storage space for that literal would contain:

'ABxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' (where "x" represents a blank space)

The second rule is that character literals longer than 32 bytes are converted to a variable of the same length as the literal value itself, as in the following example:

Call PgmB 'This is a long character literal that will exceed 32 bytes.'

the associated storage space for that literal would contain:

'This is a long character literal that will exceed 32 bytes.'

Finally, since the logical data type follows the same rules as the character type, and the only possible values for a logical data type are '0' or '1', we know that a logical literal will always be created as a 32 byte, left justified, padded character variable.

Parameter Problems

In the beginning of this explanation, you learned that it was important for the parameter declarations to match between a called program and it's caller. Then you discovered that the system sometimes has to take it upon itself to declare the parameters of the caller on your behalf. If the two declarations don't match, we have the potential for trouble.

In the case of a decimal value, the result is immediate and obvious; you get a data decimal error. Character variables are more difficult to debug because they don't generate any immediate errors. What actually happens depends upon the length of the parameter in the called program.

If the length of the parameter in the called program is less than the length of the parameter being passed, the extra characters are effectively truncated, as follows:


Call SomePgm ('ABCDEFG') /* system creates 32 byte *CHAR*/

SomePgm: Pgm Parm( &i_Var1 )

DCL &i_Var1 *CHAR 4

EndPgm

What happens is that the system passes 'ABCDEFGxxxxxxxxxxxxxxxxxxxxxxxxx' ('x' is a blank), but because of the declared length of &i_Var1, SomePgm only see's 'ABCD'. For most of us, this is the behaviour that we would expect.

Things get nasty when the declared length of the variable is longer than what is being passed in. Using the same example as we've just seen above:

SomePgm: Pgm Parm( &i_Var1 )

DCL &i_Var1 *CHAR 34

EndPgm

In this case, the system will still allocate 32 bytes of storage and assign 'ABCDEFGxxxxxxxxxxxxxxxxxxxxxxxxx' to it, but because &i_Var1 is now declared to be 34 bytes long, SomePgm will see more storage than it was intended to. It will see the 32 bytes that were allocated for it, plus two additional bytes. It's those two additional bytes that can cause the infamous "unpredictable results" which IBM's documentation often refers to.

If the extra bytes contain blanks, chances are that you won't notice a problem, but if they contain something else, your input parameter will contain "garbage".

As you can see, when dealing with literals, the magic number for character parameters is 32. If the called program declares the parameter to be less than or equal to 32, you'll never see "garbage" in the parameter. Once you cross that 32 byte threshhold, you need to take extra care to ensure that the size of the literal being passed is equal to the declared size of the input parameter.

Things to Remember

  • always match the type/size of parameters on your pgm to pgm calls.
  • remember that the system converts literals to variables in the background.
  • remember that decimal literals are always converted to *DEC(15 5).
  • and that char literals less than or equal to 32 bytes are converted to *CHAR(32).
  • and that char literals greater than 32 bytes are converted to variables of equivalent size.

and last, but not least:

  • the called program "sees" as much storage as it declares for an input parameter, regardless of whether or not the caller actually allocated that much storage for it.

Solutions

Text by Buck.

>Wow! So what you are basically saying is
>that I shouldn't have a problem if I use
>variable lengths less than or equal to
>32, but I must use longer, to make sure
>they are the same size?
>(Which by the way was the case)

This is the assumption that is in error. Imagine being the CL program doing the SBMJOB.

CL STEP2CL

dcl &filename *char 50
chgvar &filename 'test.txt'
sbmjob cmd(call STEP3CL &filename)

STEP2CL has set aside 50 bytes of storage for &FILENAME. When STEP2CL calls another program, he passes a pointer to his internal storage (parameters are passed by reference.) Well, on the AS/400 one job doesn't get to manipulate storage in another job (SBMJOB creates another job) so this can't work like a CALL.

Instead, SBMJOB resolves the value of &FILENAME and passes it to the newly created job (which is QCMD - look at your routing entries) as a constant. So instead of "call step3cl

" you get "CALL QCMD PARM(call step3cl 'test.txt')" (not really but why add request message processing to the muddle?)

QCMD parses out the string that it received and realises that it has to create some storage for the parameter 'test.txt' Because it is a character constant, QCMD creates a 32 byte storage area, initialises it to blanks and loads the constant into it, left-justified. QCMD then does a "call STEP3CL

"

CL STEP3CL

pgm &filename
dcl &filename *char 50

When STEP3CL tries to use &FILENAME, it reads 50 characters starting at

Unfortunately, QCMD only initialised 32 bytes of that area (PARAMETER SIZE MISMATCH ALERT) so the remaining bytes of &FILENAME contain Who Knows What, also known as Garbage.

A work-around:

Have STEP2CL pass 51 bytes of data to SBMJOB. Here's how that would work:

CL STEP2CL

dcl &filename *char 50
dcl &filetemp *char 51
chgvar &filename 'test.txt'
chgvar &filetemp (&filename *cat 'x')
sbmjob cmd(call STEP3CL &filename)

STEP2CL has set aside 51 bytes of storage for &FILETEMP. When the SBMJOB resolves the value of &FILETEMP, you get "CALL QCMD PARM(call step3cl 'test.txt x')" QCMD does his thing and sees 51 bytes of data, so he allocates an internal work area 51 bytes long. When STEP3CL tries to use &FILENAME, it reads 50 characters starting at

He doesn't care that QCMD has initialised 51 bytes of storage, or that byte 51 contains something: he stops reading at byte 50.

The Cool Way:

Write your own command. We've been able to extend OS/400 since the dinosaurs roamed Pangaea. Here's how it works:

CMD CVTTOPDF
CMD 'Convert IFS file to PDF'

PARM KWD(FILENAME) TYPE(*PNAME) LEN(50) MIN(1) +
PROMPT('Input file name')

crtcmd cvttopdf pgm(STEP3CL)

CL STEP2CL

dcl &filename *char 50
chgvar &filename 'test.txt'
sbmjob cmd(cvttopdf filename(&filename))

The SBMJOB results in "cvttopdf filename('test.txt')" When QCMD does his thing, he sees that he needs to run a command (not CALL) so the command processor checks the command definition for each parameter, initialises the defined amount of storage (here it's 50 bytes) loads the internal storage areas up and away we go. When STEP3CL gets called as a result of processing CVTTOPDF, his definition of 50 bytes exactly matches the caller's definition of 50 bytes and All Is Well.

Wednesday, December 19, 2007

C Interview Questions - Part 14


8.1 Why doesn't

strcat(string, '!');

work?

8.2 I'm checking a string to see if it matches a particular value. Why isn't this code working?

char *string;
...
if(string == "value") {
/* string matches "value" */
...
}

8.3 If I can say

char a[] = "Hello, world!";

why can't I say

char a[14];
a = "Hello, world!";

8.4 I can't get strcat to work. I tried

char *s1 = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);

but I got strange results.

8.5 What is the difference between these initializations?

char a[] = "string literal";
char *p = "string literal";

My program crashes if I try to assign a new value to p[i].

8.6 How can I get the numeric value (i.e. ASCII or other character set code) corresponding to a character, or vice versa?

8.7 Does C have anything like the ``substr'' (extract substring) routine present in other languages?

8.8 I'm reading strings typed by the user into an array, and then printing them out later. When the user types a sequence like \n, why isn't it being handled properly?

8.9 I think something's wrong with my compiler: I just noticed that sizeof('a') is 2, not 1 (i.e. not sizeof(char)).

8.10 I'm starting to think about multinational character sets, and I'm worried about the implications of making sizeof(char) be 2 so that 16-bit character sets can be represented.

C Interview Questions - Part 13

7.1 Why doesn't this fragment work?

char *answer;
printf("Type something:\n");
gets(answer);
printf("You typed \"%s\"\n", answer);

7.2 I can't get strcat to work. I tried

char *s1 = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);

but I got strange results.

7.3 But the man page for strcat says that it takes two char *'s as arguments. How am I supposed to know to allocate things?

7.3b I just tried the code

char *p;
strcpy(p, "abc");

and it worked. How? Why didn't it crash?

7.3c How much memory does a pointer variable allocate?

7.4 I'm reading lines from a file into an array, with this code:

char linebuf[80];
char *lines[100];
int i;

for(i = 0; i <>
char *p = fgets(linebuf, 80, fp);
if(p == NULL) break;
lines[i] = p;
}

Why do all the lines end up containing copies of the last line?

7.5a I have a function that is supposed to return a string, but when it returns to its caller, the returned string is garbage.

7.5b So what's the right way to return a string or other aggregate?

7.6 Why am I getting ``warning: assignment of pointer from integer lacks a cast'' for calls to malloc?

7.7 Why does some code carefully cast the values returned by malloc to the pointer type being allocated?

7.7b What's wrong with casting malloc's return value?

7.7c In a call to malloc, what does an error like ``Cannot convert `void *' to `int *''' mean?

7.8 I see code like

char *p = malloc(strlen(s) + 1);
strcpy(p, s);

Shouldn't that be malloc((strlen(s) + 1) * sizeof(char))?

7.9 I wrote a little wrapper around malloc, but it doesn't work:

#include
#include

mymalloc(void *retp, size_t size)
{
retp = malloc(size);
if(retp == NULL) {
fprintf(stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
}

7.10 I'm trying to declare a pointer and allocate some space for it, but it's not working. What's wrong with this code?

char *p;
*p = malloc(10);

7.10a What's wrong with this initialization?

char *p = malloc(10);

My compiler is complaining about an ``invalid initializer'', or something.

7.10b How can I shut off the ``warning: possible pointer alignment problem'' message which lint gives me for each call to malloc?

7.11 How can I dynamically allocate arrays?

7.12 How can I find out how much memory is available?

7.13 What should malloc(0) do? Return a null pointer or a pointer to 0 bytes?

7.14 I've heard that some operating systems don't actually allocate malloc'ed memory until the program tries to use it. Is this legal?

7.15 malloc is returning crazy pointer values, but I did read question 7.6 and I have included the line

extern void *malloc();

before I call it.

7.16 I'm allocating a large array for some numeric work, using the line

double *array = malloc(300 * 300 * sizeof(double));

malloc isn't returning null, but the program is acting strangely, as if it's overwriting memory, or malloc isn't allocating as much as I asked for, or something.

7.17 I've got 8 meg of memory in my PC. Why can I only seem to malloc 640K or so?

7.18 My application depends heavily on dynamic allocation of nodes for data structures, and malloc/free overhead is becoming a bottleneck. What can I do?

7.19 My program is crashing, apparently somewhere down inside malloc, but I can't see anything wrong with it. Is there a bug in malloc?

7.19b

I'm dynamically allocating an array, like this:

int *iarray = (int *)malloc(nints);

malloc isn't returning NULL, but the code isn't working.

7.20 You can't use dynamically-allocated memory after you free it, can you?

7.21 Why isn't a pointer null after calling free?
How unsafe is it to use (assign, compare) a pointer value after it's been freed?

7.22 When I call malloc to allocate memory for a pointer which is local to a function, do I have to explicitly free it?

7.23 I'm allocating structures which contain pointers to other dynamically-allocated objects. When I free a structure, do I also have to free each subsidiary pointer?

7.24 Must I free allocated memory before the program exits?

7.25 I have a program which mallocs and later frees a lot of memory, but I can see from the operating system that memory usage doesn't actually go back down.

7.26 How does free know how many bytes to free?

7.27 So can I query the malloc package to find out how big an allocated block is?

7.28 Why doesn't sizeof tell me the size of the block of memory pointed to by a pointer?

7.29 Having dynamically allocated an array (as in question 6.14), can I change its size?

7.30 Is it legal to pass a null pointer as the first argument to realloc? Why would you want to?

7.31 What's the difference between calloc and malloc? Which should I use? Is it safe to take advantage of calloc's zero-filling? Does free work on memory allocated with calloc, or do you need a cfree?

7.32 What is alloca and why is its use discouraged?

C Interview Questions - Part 12

6.1 I had the definition char a[6] in one source file, and in another I declared extern char *a. Why didn't it work?

6.2 But I heard that char a[] was identical to char *a.

6.3 So what is meant by the ``equivalence of pointers and arrays'' in C?

6.4 If they're so different, then why are array and pointer declarations interchangeable as function formal parameters?

6.4b So arrays are passed by reference, even though the rest of C uses pass by value?

6.5 Why can't I do something like this?

extern char *getpass();
char str[10];
str = getpass("Enter password: ");

6.6 If you can't assign to arrays, then how can

int f(char str[])
{
if(str[0] == '\0')
str = "none";
...
}

work?

6.6b And what about this? Isn't this an array assignment?

char a[] = "Hello, world!\n";

6.7 How can an array be an lvalue, if you can't assign to it?

6.8 Practically speaking, what is the difference between arrays and pointers?

6.9 Someone explained to me that arrays were really just constant pointers.

6.10 I'm still mystified. Is a pointer a kind of array, or is an array a kind of pointer?

6.11 I came across some ``joke'' code containing the ``expression'' 5["abcdef"] . How can this be legal C?

6.12 Since array references decay into pointers, if arr is an array, what's the difference between arr and &arr?

6.13 How do I declare a pointer to an array?

6.14 How can I set an array's size at run time?
How can I avoid fixed-sized arrays?

6.15 How can I declare local arrays of a size matching a passed-in array?

6.16 How can I dynamically allocate a multidimensional array?

6.17 Here's a neat trick: if I write

int realarray[10];
int *array = &realarray[-1];

I can treat array as if it were a 1-based array.

6.18 My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.

6.19 How do I write functions which accept two-dimensional arrays when the width is not known at compile time?

6.20 How can I use statically- and dynamically-allocated multidimensional arrays interchangeably when passing them to functions?

6.21 Why doesn't sizeof properly report the size of an array when the array is a parameter to a function? I have a test routine

f(char a[10])
{
int i = sizeof(a);
printf("%d\n", i);
}

and it prints 4, not 10.

6.22 How can code in a file where an array is declared as extern (i.e. it is defined, and its size determined, in some other file) determine the size of the array? sizeof doesn't seem to work.

6.23 I want to know how many elements are in an array, but sizeof yields the size in bytes.

6.24 Is there a way to have an array of bits?

C Interview Questions - Part 11

5.1 What is this infamous null pointer, anyway?

5.2 How do I get a null pointer in my programs?

5.3 Is the abbreviated pointer comparison ``if(p)'' to test for non-null pointers valid? What if the internal representation for null pointers is nonzero?

5.4 What is NULL and how is it defined?

5.5 How should NULL be defined on a machine which uses a nonzero bit pattern as the internal representation of a null pointer?

5.6 If NULL were defined as follows:

#define NULL ((char *)0)

wouldn't that make function calls which pass an uncast NULL work?

5.7 My vendor provides header files that #define NULL as 0L. Why?

5.8 Is NULL valid for pointers to functions?

5.9 If NULL and 0 are equivalent as null pointer constants, which should I use?

5.10 But wouldn't it be better to use NULL (rather than 0), in case the value of NULL changes, perhaps on a machine with nonzero internal null pointers?

5.11 I once used a compiler that wouldn't work unless NULL was used.

5.12 I use the preprocessor macro

#define Nullptr(type) (type *)0

to help me build null pointers of the correct type.

5.13 This is strange. NULL is guaranteed to be 0, but the null pointer is not?

5.14 Why is there so much confusion surrounding null pointers? Why do these questions come up so often?

5.15 I'm confused. I just can't understand all this null pointer stuff.

5.16 Given all the confusion surrounding null pointers, wouldn't it be easier simply to require them to be represented internally by zeroes?

5.17 Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?

5.18 Is a run-time integral value of 0, cast to a pointer, guaranteed to be a null pointer?

5.19 How can I access an interrupt vector located at the machine's location 0? If I set a pointer to 0, the compiler might translate it to some nonzero internal null pointer value.

5.20 What does a run-time ``null pointer assignment'' error mean? How can I track it down?

Tuesday, December 18, 2007

C Interview Questions - Part 10

4.1 What are pointers really good for, anyway?

4.2 I'm trying to declare a pointer and allocate some space for it, but it's not working. What's wrong with this code?

char *p;
*p = malloc(10);

4.3 Does *p++ increment p, or what it points to?

4.4 I'm trying to use pointers to manipulate an array of ints. What's wrong with this code?

int array[5], i, *ip;
for(i = 0; i <>
ip = array;
printf("%d\n", *(ip + 3 * sizeof(int)));

I expected the last line to print 3, but it printed garbage.

4.5 I have a char * pointer that happens to point to some ints, and I want to step it over them. Why doesn't

((int *)p)++;

work?

4.6 Why can't I perform arithmetic on a void * pointer?

4.7 I've got some code that's trying to unpack external structures, but it's crashing with a message about an ``unaligned access.'' What does this mean?

4.8 I have a function which accepts, and is supposed to initialize, a pointer:

void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}

But when I call it like this:

int *ip;
f(ip);

the pointer in the caller remains unchanged.

4.9 Suppose I want to write a function that takes a generic pointer as an argument and I want to simulate passing it by reference. Can I give the formal parameter type void **, and do something like this?

void f(void **);
double *dp;
f((void **)&dp);

4.10 I have a function

extern int f(int *);

which accepts a pointer to an int. How can I pass a constant by reference? A call like

f(&5);

doesn't seem to work.

4.11 Does C even have ``pass by reference''?

4.12 I've seen different syntax used for calling functions via pointers. What's the story?

4.13 What's the total generic pointer type? My compiler complained when I tried to stuff function pointers into a void *.

4.14 How are integers converted to and from pointers? Can I temporarily stuff an integer into a pointer, or vice versa?

4.15 How do I convert an int to a char *? I tried a cast, but it's not working.

4.16 What's wrong with this declaration?

char* p1, p2;

I get errors when I try to use p2.

4.17 What are ``near'' and ``far'' pointers?

C Interview Questions - Part 9

3.1 Why doesn't this code:

a[i] = i++;

work?

3.2 Under my compiler, the code

int i = 7;
printf("%d\n", i++ * i++);

prints 49. Regardless of the order of evaluation, shouldn't it print 56?

3.3 I've experimented with the code

int i = 3;
i = i++;

on several compilers. Some gave i the value 3, and some gave 4. Which compiler is correct?

3.3b Here's a slick expression:

a ^= b ^= a ^= b

It swaps a and b without using a temporary.

3.4 Can I use explicit parentheses to force the order of evaluation I want, and control these side effects? Even if I don't, doesn't precedence dictate it?

3.5 But what about the && and || operators?
I see code like ``while((c = getchar()) != EOF && c != '\n')'' ...

3.6 Is it safe to assume that the right-hand side of the && and || operators won't be evaluated if the left-hand side determines the outcome?

3.7 Why did

printf("%d %d", f1(), f2());

call f2 first? I thought the comma operator guaranteed left-to-right evaluation.

3.8 How can I understand complex expressions like the ones in this section, and avoid writing undefined ones? What's a ``sequence point''?

3.9 So if I write

a[i] = i++;

and I don't care which cell of a[] gets written to, the code is fine, and i gets incremented by one, right?

3.10a People keep saying that the behavior of i = i++ is undefined, but I just tried it on an ANSI-conforming compiler, and got the results I expected.

3.10b People told me that if I evaluated an undefined expression, or accessed an uninitialized variable, I'd get a random, garbage value. But I tried it, and got zero. What's up with that?

3.11 How can I avoid these undefined evaluation order difficulties if I don't feel like learning the complicated rules?

3.12a What's the difference between ++i and i++?

3.12b If I'm not using the value of the expression, should I use ++i or i++ to increment a variable?

3.13 I need to check whether one number lies between two others. Why doesn't

if(a < b < c)

work?

3.14 Why doesn't the code

int a = 1000, b = 1000;
long int c = a * b;

work?

3.14b How can I ensure that integer arithmetic doesn't overflow?

3.15 Why does the code

double degC, degF;
degC = 5 / 9 * (degF - 32);

keep giving me 0?

3.16 I have a complicated expression which I have to assign to one of two variables, depending on a condition. Can I use code like this?

((condition) ? a : b) = complicated_expression;

3.17 I have some code containing expressions like

a ? b = c : d

and some compilers are accepting it but some are not.

3.18 What does the warning ``semantics of `>' change in ANSI C'' mean?

3.19 What's the difference between the ``unsigned preserving'' and ``value preserving'' rules?

C Interview Questions - Part 8

2.1 What's the difference between these two declarations?

struct x1 { ... };
typedef struct { ... } x2;

2.2 Why doesn't

struct x { ... };
x thestruct;

work?

2.3 Can a structure contain a pointer to itself?

2.4 How can I implement opaque (abstract) data types in C?

2.4b Is there a good way of simulating OOP-style inheritance, or other OOP features, in C?

2.5 Why does the declaration

extern int f(struct x *p);

give me an obscure warning message about ``struct x declared inside parameter list''?

2.6 I came across some code that declared a structure like this:

struct name {
int namelen;
char namestr[1];
};

and then did some tricky allocation to make the namestr array act like it had several elements, with the number recorded by namelen. How does this work? Is it legal or portable?

2.7 I heard that structures could be assigned to variables and passed to and from functions, but K&R1 says not.

2.8 Is there a way to compare structures automatically?

2.9 How are structure passing and returning implemented?

2.10 How can I pass constant values to functions which accept structure arguments? How can I create nameless, immediate, constant structure values?

2.11 How can I read/write structures from/to data files?

2.12 Why is my compiler leaving holes in structures, wasting space and preventing ``binary'' I/O to external data files? Can I turn this off, or otherwise control the alignment of structure fields?

2.13 Why does sizeof report a larger size than I expect for a structure type, as if there were padding at the end?

2.14 How can I determine the byte offset of a field within a structure?

2.15 How can I access structure fields by name at run time?

2.16 Does C have an equivalent to Pascal's with statement?

2.17 If an array name acts like a pointer to the base of an array, why isn't the same thing true of a structure?

2.18 This program works correctly, but it dumps core after it finishes. Why?

struct list {
char *item;
struct list *next;
}

/* Here is the main program. */

main(argc, argv)
{ ... }

2.19 What's the difference between a structure and a union, anyway?

2.20 Can I initialize unions?

2.21 Is there an automatic way to keep track of which field of a union is in use?

2.22 What's the difference between an enumeration and a set of preprocessor #defines?

2.23 Are enumerations really portable?
Aren't they Pascalish?

2.24 Is there an easy way to print enumeration values symbolically?

2.25 I came across some structure declarations with colons and numbers next to certain fields, like this:

struct record {
char *name;
int refcount : 4;
unsigned dirty : 1;
};

What gives?

2.26 Why do people use explicit masks and bit-twiddling code so much, instead of declaring bit-fields?

C Interview Questions - Part 7

1.1 How should I decide which integer type to use?

1.2 Why aren't the sizes of the standard types precisely defined?

1.3 Since C doesn't define sizes exactly, I've been using typedefs like int16 and int32. I can then define these typedefs to be int, short, long, etc. depending on what machine I'm using. That should solve everything, right?

1.4 What should the 64-bit type be on a machine that can support it?

1.5 What's wrong with this declaration?

char* p1, p2;

I get errors when I try to use p2.

1.6 I'm trying to declare a pointer and allocate some space for it, but it's not working. What's wrong with this code?

char *p;
*p = malloc(10);

1.7 What's the best way to declare and define global variables and functions?

1.8 How can I implement opaque (abstract) data types in C?

1.9 How can I make a sort of ``semi-global'' variable, that is, one that's private to a few functions spread across a few source files?

1.10 Do all declarations for the same static function or variable have to include the storage class static?

1.11 What does extern mean in a function declaration?

1.12 What's the auto keyword good for?

1.13 What's the difference between using a typedef or a #define for a user-defined type?

1.14 I can't seem to define a linked list successfully. I tried

typedef struct {
char *item;
NODEPTR next;
} *NODEPTR;

but the compiler gave me error messages. Can't a structure in C contain a pointer to itself?

1.15 How can I define a pair of mutually referential structures? I tried

typedef struct {
int afield;
BPTR bpointer;
} *APTR;

typedef struct {
int bfield;
APTR apointer;
} *BPTR;

but the compiler doesn't know about BPTR when it is used in the first structure declaration.

1.16 What's the difference between these two declarations?

struct x1 { ... };
typedef struct { ... } x2;

1.17 What does

typedef int (*funcptr)();

mean?

1.18 I've got the declarations

typedef char *charp;
const charp p;

Why is p turning out const, instead of the characters pointed to?

1.19 I don't understand why I can't use const values in initializers and array dimensions, as in

const int n = 5;
int a[n];

1.20 What's the difference between const char *p, char const *p, and char * const p?

1.20b

What does it mean for a function parameter to be const? What do the two const's in

int f(const * const p)

mean?

1.21 How do I construct declarations of complicated types such as ``array of N pointers to functions returning pointers to functions returning pointers to char'', or figure out what similarly complicated declarations mean?

1.22 How can I declare a function that can return a pointer to a function of the same type? I'm building a state machine with one function for each state, each of which returns a pointer to the function for the next state. But I can't find a way to declare the functions--I seem to need a function returning a pointer to a function returning a pointer to a function returning a pointer to a function..., ad infinitum.

1.23 Can I declare a local array (or parameter array) of a size matching a passed-in array, or set by another parameter?

1.24 I have an extern array which is defined in one file, and used in another:

file1.c: file2.c:

int array[] = {1, 2, 3}; extern int array[];

Why doesn't sizeof work on array in file2.c?

1.25 My compiler is complaining about an invalid redeclaration of a function, but I only define it once and call it once.

1.25b What's the right declaration for main?
Is void main() correct?

1.26 My compiler is complaining about mismatched function prototypes which look fine to me.

1.27 I'm getting strange syntax errors on the very first declaration in a file, but it looks fine.

1.28 My compiler isn't letting me declare a big array like

double array[256][256];

1.29 How can I determine which identifiers are safe for me to use and which are reserved?

1.30 What am I allowed to assume about the initial values of variables and arrays which are not explicitly initialized?
If global variables start out as ``zero'', is that good enough for null pointers and floating-point zeroes?

1.31 This code, straight out of a book, isn't compiling:

int f()
{
char a[] = "Hello, world!";
}

1.31b What's wrong with this initialization?

char *p = malloc(10);

My compiler is complaining about an ``invalid initializer'', or something.

1.32 What is the difference between these initializations?

char a[] = "string literal";
char *p = "string literal";

My program crashes if I try to assign a new value to p[i].

1.33 Is char a[3] = "abc"; legal?

1.34 I finally figured out the syntax for declaring pointers to functions, but now how do I initialize one?

1.35 Can I initialize unions?

C Interview Questions - Part 6

11.5: Why does the declaration
extern int f(struct x *p);
give me an obscure warning message about "struct x introduced in
prototype scope"?
---
give me an obscure warning message about "struct x declared
inside parameter list"?
==========
A: "const char *p" (which can also be written "char const *p")
declares a pointer to a constant character (you can't change
the character); "char * const p" declares a constant pointer
---
any pointed-to characters); "char * const p" declares a constant
pointer to a (variable) character (i.e. you can't change the
pointer).
==========
A: The problem is older linkers which are under the control of
---
A: The problem is linkers which are under control of
neither the ANSI/ISO Standard nor the C compiler developers
on the systems which have them.
==========
If you're interested in writing portable code, you can ignore
the distinctions, as you'll want to avoid code that depends
---
the distinctions, as you'll usually want to avoid code that
depends on any of the three behaviors.
==========
A: The functions in locale.h begin to provide some support for
these operations, but there is no standard routine for doing
---
these operations, but there is no standard function for doing
either task.
==========
If you're worried about using floating point, you could use
---
If you'd rather not use floating point, another method is
rand() / (RAND_MAX / N + 1)
==========
A: In general, a header file contains only declarations.
---
A: In general, a header file contains only external declarations.
==========
how carefully your compiler's binary/decimal conversion routines
(such as those used by printf) have been written, you may see
discrepancies when numbers (especially low-precision floats) not
exactly representable in base 2 are assigned or read in and then
---
discrepancies when numbers not exactly representable in base 2
are assigned or read in and then printed (i.e. converted from
base 10 to base 2 and back again).
==========
Another possibility is to to format the value in question using
---
Another possibility is to format the value in question using
sprintf(): on many systems it generates strings like "NaN"
==========
A: Some compilers for small machines, including Borland's
---
A: Some compilers for small machines, including Turbo C
Ritchie's original PDP-11 compiler), leave out certain floating
==========
char *vstrcat(char *first, ...)
---
char *vstrcat(const char *first, ...)
==========
void error(char *fmt, ...)
---
void error(const char *fmt, ...)
==========
examples in questions 5.2 and 15.4). Finally, if their types
---
examples in questions 5.2 and 15.4). Finally, if the types
are predictable, you can pass an explicit count of the number of
==========
local arrays. Many systems have fixed-size stacks, and
---
local arrays. Many systems have fixed-size stacks, and even
those which perform dynamic stack allocation automatically
(e.g. Unix) can be confused when the stack tries to grow by a
huge chunk all at once.
==========
16.8: What do "Segmentation violation" and "Bus error" mean?
---
16.8: What do "Segmentation violation", "Bus error", and "General
protection fault" mean?
==========
Finally, the author of this FAQ list teaches a C class
and has placed its notes on the web; they are at
---
Finally, the author of this FAQ list once taught a couple of
C classes and has placed their notes on the web; they are at
==========
18.10: What's a good book for learning C?
---
18.10: What's a good book for learning C? What about advanced books
and references?
==========
The GNU libplot package maintains the same spirit and supports
many modern plot devices;
see http://www.gnu.org/software/plotutils/plotutils.html .
---
The GNU libplot library, written by Robert Maier, maintains
the same spirit and supports many modern plot devices; see
http://www.gnu.org/software/plotutils/plotutils.html .
==========
A: If the "size of a file" is the number of characters you'll be
able to read from it in C, it is difficult or impossible to
---
able to read from it in C, it can be difficult or impossible to
determine this number exactly.
==========
readdir() only returns file names; if you need more
---
readdir() returns just the file names; if you need more
information about the file, try calling stat().
==========
(Also, remember to call pclose().)
---
(Also, remember to call pclose() when you're done.)
==========
busy-wait, but this is only an option on a single-user, single-
tasking machine as it is terribly antisocial to any other
---
tasking machine, as it is terribly antisocial to any other
processes. Under a multitasking operating system, be sure to
==========
It is possible, and desirable, for *most* of a program to be
ANSI-compatible, deferring the system-dependent functionality to
a few routines in a few files which are rewritten for each
system ported to.
---
a few routines in a few files which are either heavily #ifdeffed
or rewritten entirely for each system ported to.
==========
or have the function return a structure containing the
desired values, or (in a pinch) consider global variables.
---
desired values, or (in a pinch) you could theoretically use
global variables.
==========
is not only clearer to the human reader, it is more likely to be
recognized by the compiler and turned into the most-efficient
code (e.g. using a swap instruction, if available).
---
code (e.g. perhaps even using an EXCH instruction).
==========
More information may be found in FORT.gz by Glenn Geers, available
via anonymous ftp from suphys.physics.su.oz.au in the src
directory.

cfortran.h, a C header file, simplifies C/FORTRAN interfacing on
many popular machines. It is available via anonymous ftp from
zebra.desy.de or at http://www-zeus.desy.de/~burow .
---
For FORTRAN, more information may be found in FORT.gz by Glenn
Geers, available via anonymous ftp from suphys.physics.su.oz.au
in the src directory. Burkhard Burow's header file cfortran.h
simplifies C/FORTRAN interfacing on many popular machines.
It is available via anonymous ftp from zebra.desy.de or at
http://www-zeus.desy.de/~burow .
==========
This FAQ list's maintainer also has available a list of a few
other commercial translation products, and some for more obscure
languages.
---
other translators.
==========
A: The contest is in a state of flux; see
---
A: The contest schedule varies over time; see
====================


Finally, here are a few questions which don't really need to be in
the posted-to-Usenet list every month. (As mentioned, though, they'll
live on in the web-based version.)

==========

1.22: How can I declare a function that can return a pointer to a
function of the same type? I'm building a state machine with
one function for each state, each of which returns a pointer to
the function for the next state. But I can't find a way to
declare the functions.

A: You can't quite do it directly. Either have the function return
a generic function pointer, with some judicious casts to adjust
the types as the pointers are passed around; or have it return a
structure containing only a pointer to a function returning that
structure.

==========

2.7: I heard that structures could be assigned to variables and
passed to and from functions, but K&R1 says not.

A: What K&R1 said (though this was quite some time ago by now) was
that the restrictions on structure operations would be lifted
in a forthcoming version of the compiler, and in fact structure
assignment and passing were fully functional in Ritchie's
compiler even as K&R1 was being published. A few ancient C
compilers may have lacked these operations, but all modern
compilers support them, and they are part of the ANSI C
standard, so there should be no reluctance to use them.

(Note that when a structure is assigned, passed, or returned,
the copying is done monolithically; the data pointed to by any
pointer fields is *not* copied.)

==========

13.14b: Does C have any Year 2000 problems?

A: No, although poorly-written C programs do.

The tm_year field of struct tm holds the value of the year minus
1900; this field will therefore contain the value 100 for the
year 2000. Code that uses tm_year correctly (by adding or
subtracting 1900 when converting to or from human-readable
4-digit year representations) will have no problems at the turn
of the millennium. Any code that uses tm_year incorrectly,
however, such as by using it directly as a human-readable
2-digit year, or setting it from a 4-digit year with code like

tm.tm_year = yyyy % 100; /* WRONG */

or printing it as an allegedly human-readable 4-digit year with
code like

printf("19%d", tm.tm_year); /* WRONG */

will have grave y2k problems indeed. See also question 20.32.

==========

13.24: I'm trying to port this A: Those functions are variously
old program. Why do I obsolete; you should
get "undefined external" instead:
errors for:

index? use strchr.
rindex? use strrchr.
bcopy? use memmove, after
interchanging the first and
second arguments (see also
question 11.25).
bcmp? use memcmp.
bzero? use memset, with a second
argument of 0.

==========

15.7: I have a pre-ANSI compiler, without stdarg.h. What can I do?

A: There's an older header, varargs.h, which offers about the
same functionality.

==========

18.5: How can I shut off the "warning: possible pointer alignment
problem" message which lint gives me for each call to malloc()?

A: The problem is that traditional versions of lint do not know,
and cannot be told, that malloc() "returns a pointer to space
suitably aligned for storage of any type of object." It is
possible to provide a pseudoimplementation of malloc(), using a
#define inside of #ifdef lint, which effectively shuts this
warning off, but a simpleminded definition will also suppress
meaningful messages about truly incorrect invocations. It may
be easier simply to ignore the message, perhaps in an automated
way with grep -v. (But don't get in the habit of ignoring too
many lint messages, otherwise one day you'll overlook a
significant one.)

C Interview Questions Part - 5


1.1: How do you decide which integer type to use?
---
1.1: How should I decide which integer type to use?
==========
float and double. None of the above rules apply if the address
of a variable is taken and must have a particular type.
---
float and double. None of the above rules apply if pointers to
the variable must have a particular type.
==========
1.4: What should the 64-bit type on a machine that can support it?
---
1.4: What should the 64-bit type be on a machine that can support it?
==========
The .c file containing the definition should also #include the
same header file, so that the compiler can check that the definition
---
same header file, so the compiler can check that the definition
matches the declarations.
==========
clear. The problem with the NODEPTR example is that the typedef
has not been defined at the point where the "next" field is
---
has not yet been defined at the point where the "next" field is
declared.
==========
1.21: How do I declare an array of N pointers to functions returning
pointers to functions returning pointers to characters?
---
1.21: How do I construct and understand declarations of complicated
types such as "array of N pointers to functions returning
pointers to functions returning pointers to char"?
==========
A: The first part of this question can be answered in at least
three ways:
---
A: There are at least three ways of answering this question:
==========
cdecl can also explain complicated declarations, help with
casts, and indicate which set of parentheses the arguments
---
casts, and indicate which set of parentheses the parameters
go in
==========
Any good book on C should explain how to read these complicated C
---
A good book on C should explain how to read these complicated
declarations "inside out" to understand them ("declaration
mimics use").
==========
1.30: What am I allowed to assume about the initial values
of variables which are not explicitly initialized?
---
of variables and arrays which are not explicitly initialized?
==========
A: Uninitialized variables with "static" duration (that is, those
declared outside of functions, and those declared with the
storage class static), are guaranteed to start out as zero,
---
storage class static), are guaranteed to start out as zero, just
as if the programmer had typed "= 0".
==========
A: Is the declaration of a static or non-local variable? Function
calls are allowed only in initializers for automatic variables
---
calls are allowed in initializers only for automatic variables
==========
A: A string literal can be used in two slightly different ways. As
an array initializer (as in the declaration of char a[]), it
---
an array initializer (as in the declaration of char a[] in the
question), it specifies the initial values of the characters in
that array.
==========
Anywhere else, it turns into an unnamed, static array of
characters, which may be stored in read-only memory,
which is why you can't safely modify it.
---
and which therefore cannot necessarily be modified.
==========
(For compiling old code, some compilers have a switch
controlling whether strings are writable or not.)
---
controlling whether string literals are writable or not.)
==========
When the name of a function appears in an expression like this,
---
When the name of a function appears in an expression,
it "decays" into a pointer (that is, it has its address
implicitly taken), much as an array name does.
==========
2.4: What's the best way of implementing opaque (abstract) data types
in C?
---
2.4: How can I implement opaque (abstract) data types in C?
==========
A: No. There is no single, good way for a compiler to implement
implicit structure comparison (i.e. to support the == operator
---
A: No. There is not a good way for a compiler to implement
structure comparison (i.e. to support the == operator
for structures) which is consistent with C's low-level flavor.
==========
A simple byte-by-byte comparison could founder on random bits
present in unused "holes" in the structure (such padding is used
to keep the alignment of later fields correct; see question 2.12).
---
present in unused "holes" in the structure (see question 2.12).
==========
Note also that if the structure contains any pointers, only
---
Also, if the structure contains any pointers, only
the pointer values will be written, and they are most unlikely
to be valid when read back in.
==========
Finally, note that for widespread portability you must use the
"b" flag when fopening the files; see question 12.38.
---
"b" flag when opening the files; see question 12.38.
==========
A: Structures may have this padding (as well as internal padding),
if necessary, to ensure that alignment properties will be
preserved when an array of contiguous structures is allocated.
Even when the structure is not part of an array, the end padding
---
A: Padding at the end of a structure may be necessary to preserve
alignment when an array of contiguous structures is allocated.
Even when the structure is not part of an array, the padding
remains, so that sizeof can always return a consistent size.
==========
A: At the present time, there is little difference. The C Standard
---
A: There is little difference. The C Standard
says that enumerations may be freely intermixed with other
integral types, without errors.
==========
that they obey block scope. (A compiler may also generate
nonfatal warnings when enumerations and integers are
indiscriminately mixed, since doing so can still be considered
bad style even though it is not strictly illegal.)
---
nonfatal warnings when enumerations are indiscriminately mixed,
since doing so can still be considered bad style.)
==========
(Loosely speaking, by "multiple, ambiguous side effects" we mean
any combination of ++, --, =, +=, -=, etc. in a single expression
---
any combination of increment, decrement, and assignment operators
in a single expression which causes the same object either to be
modified twice or modified and then inspected.
==========
Note that (long int)(a * b) would *not* have the desired effect.
---
Notice that (long int)(a * b) would *not* have the desired
effect.
==========
or a delibrate but nonstandard extension if a particular
---
or a deliberate but nonstandard extension if a particular
==========
Whenever possible, you should choose appropriate pointer types
in the first place, instead of trying to treat one type
---
When possible, however, you should choose appropriate pointer
types in the first place, rather than trying to treat one type
as another.
==========
void * acts as a generic pointer only because conversions are
---
void * acts as a generic pointer only because conversions (if
necessary) are applied automatically when other pointer types
are assigned to and from void *'s;
==========
4.12: I've seen different methods used for calling functions via
---
4.12: I've seen different syntax used for calling functions via
pointers. What's the story?
==========
pointers, and that "real" function names always decay implicitly
into pointers (in expressions, as they do in initializations;
see question 1.34). This reasoning (which is in fact used in
the ANSI standard) means that
---
see question 1.34). This reasoning means that
==========
function pointer followed by an argument list except call the
function pointed to.) An explicit * is still allowed.
---
function pointed to.)
==========
The ANSI C Standard essentially adopts the latter
interpretation, meaning that the explicit * is not required,
though it is still allowed.
==========
5.4: What is NULL and how is it #defined?
---
5.4: What is NULL and how is it defined?
==========
preprocessor macro NULL is #defined (by stdio.h and several
other headers) with the value 0, possibly cast to (void *)
---
preprocessor macro NULL is defined (by stdio.h and several
other headers) as a null pointer constant, typically 0 or
((void *)0)
==========
NULL should *only* be used for pointers; see question 5.9.
---
NULL should be used *only* as a pointer constant; see question 5.9.
==========
A: Not in general. The complication is that there are machines
---
A: Not in the most general case. The complication is that there
are machines which use different internal representations for
pointers to different types of data.
==========
pointer arguments of other types would still be problematical,
---
pointer arguments of other types could still (in the absence
of prototypes) be problematical,
==========
This article uses the phrase "null pointer" (in lower case) for
sense 1, the character "0" or the phrase "null pointer constant"
---
sense 1, the token "0" or the phrase "null pointer constant"
for sense 3, and the capitalized word "NULL" for sense 4.
==========
A: C programmers traditionally like to know more than they might
need to about the underlying machine implementation.
---
A: C programmers traditionally like to know a lot (perhaps more
than they need to) about the underlying machine implementation.
==========
integer zero instead of an error message, and if that uncast 0
was supposed to be a null pointer constant, the code may not
work.
---
was supposed to be a null pointer constant, the resulting
program may not work.
==========
Some 64-bit Cray machines represent int * in the lower 48 bits
of a word; char * additionally uses the upper 16 bits to
---
of a word; char * additionally uses some of the upper 16 bits to
indicate a byte address within a word.
==========
A: This message, which typically occurs with MS-DOS compilers, means
that you've written, via a null (perhaps because uninitialized)
pointer, to an invalid location (probably offset 0 in the
default data segment).
---
means that you've written, via a null pointer, to an invalid
location -- probably offset 0 in the default data segment.
==========
A: In one source file you defind an array of characters and in the
---
A: In one source file you defined an array of characters and in the
==========
It is important to realize that a reference like x[3] generates
---
It is useful to realize that a reference like x[3] generates
different code depending on whether x is an array or a pointer.
==========
If you can't use C9X or gcc, you'll have to use malloc(), and
---
If you can't use C99 or gcc, you'll have to use malloc(), and
remember to call free() before the function returns.
==========
Finally, in C9X you can use a variable-length array.
---
Finally, in C99 you can use a variable-length array.
==========
A: The rule (see question 6.3) by which arrays decay into pointers
is not applied recursively.
---
is *not* applied recursively.
==========
not provide an automatically-managed string type. C compilers
only allocate memory for objects explicitly mentioned in the
---
allocate memory only for objects explicitly mentioned in the
source code (in the case of strings, this includes character
==========
A: You got lucky, I guess. The memory pointed to by the
unitialized pointer p happened to be writable by you,
---
A: You got lucky, I guess. The memory randomly pointed to by
the uninitialized pointer p happened to be writable by you,
==========
A pointer value which has been freed is, strictly speaking,
invalid, and *any* use of it, even if is not dereferenced,
---
invalid, and *any* use of it, even if it is not dereferenced,
can theoretically lead to trouble,
==========
A: In C, characters are represented by small integers corresponding
to their values (in the machine's character set), so you
---
to their values in the machine's character set. Therefore, you
don't need a conversion function: if you have the character, you
have its value.
==========
DEBUG("i = %d" _ i)
---
DEBUG("i = %d" _ i);
==========
controversial trigraph sequences). The ANSI C standard also
formalizes the C run-time library support routines.
---
formalized the C run-time library support routines.

C Interview Questions Part - 4

[Q19.1 How can I read a single character from the keyboard...]

Note that the answers are often not unique even across different
variants of a system; bear in mind when answering system-
---
Note that the answers may differ even across variants of
otherwise similar systems (e.g. across different variants of
Unix); bear in mind when answering system-specific questions
that the answer that applies to your system may not apply to
everyone else's.

==========

[Q19.3 How can I display a percentage-done indication...]

current line. The character '\b' is a backspace, and will
usually move the cursor one position to the left.
---
usually move the cursor one position to the left. (But remember
to call fflush(), too.)

==========

[Q19.8 How can I direct output to the printer?]

Under some circumstances, another (and perhaps the only)
possibility is to use a window manager's screen-capture
function, and print the resulting bitmap.

==========

[Q19.10 How can I do graphics?]

A modern, platform-independent graphics library (which also
supports 3D graphics and animation) is OpenGL. Other graphics
standards which may be of interest are GKS and PHIGS.

==========

[Q19.12 How can I find out the size of a file, prior to reading it in?]

You can fseek() to the end and then use
ftell(), or maybe try fstat(), but these tend to have the same
sorts of problems: fstat() is not portable, and generally tells
you the same thing stat() tells you; ftell() is not guaranteed
to return a byte count except for binary files. Some systems
---
to return a byte count except for binary files (but, strictly
speaking, binary files don't necessarily support fseek to
SEEK_END at all). Some systems provide functions called
filesize() or filelength(), but these are obviously not
portable, either.

==========

[Q19.20 How can I read a directory in a C program?]

(MS-DOS also has FINDFIRST and FINDNEXT routines which
do essentially the same thing.)
---
do essentially the same thing, and MS Windows has FindFirstFile
and FindNextFile.)

==========

[Q19.23 How can I allocate arrays or structures bigger than 64K?]

to allocate huge amounts of it contiguously. (The C Standard
does not guarantee that single objects can be 32K or larger,
or 64K for C9X.) Often it's a good idea to use data
---
or 64K for C99.) Often it's a good idea to use data

==========

[Q19.25 How can I access memory (a memory-mapped device...]

Then, *magicloc refers to the location you want.
---
Then, *magicloc refers to the location you want. If the
location is a memory-mapped I/O register, you will probably also
want to use the volatile qualifier.

==========

[Q19.27 How can I invoke another program...]

Depending on your operating system, you may also be able to use
system calls such as exec or spawn (or execl, execv, spawnl,
spawnv, etc.).

==========

[Q19.37 How can I implement a delay... with sub-second resolution?]

A: Unfortunately, there is no portable way. V7 Unix, and derived
systems, provided a fairly useful ftime() function with
resolution up to a millisecond, but it has disappeared from
System V and POSIX. Other routines you might look for on your
---
A: Unfortunately, there is no portable way. Routines you might
look for on your system include clock(), delay(), ftime(),
gettimeofday(), msleep(), nap(), napms(), nanosleep(),
setitimer(), sleep(), Sleep(), times(), and usleep().

==========

[Q19.40 How do I... Use sockets? Do networking?]

and W. R. Stevens's _UNIX Network Programming_. There is also
plenty of information out on the net itself, including the
"Unix Socket FAQ" at http://kipper.york.ac.uk/~vic/sock-faq/
---
"Unix Socket FAQ" at http://www.developerweb.net/sock-faq/

and "Beej's Guide to Network Programming" at
http://www.ecst.csuchico.edu/~beej/guide/net/.

(One tip: depending on your OS, you may need to explicitly
request the -lsocket and -lnsl libraries; see question 13.25.)

==========

[Q20.14 Are pointers really faster than arrays?]

It is "usually" faster to march through large arrays with
---
For conventional machines, it is usually faster to march through
large arrays with pointers rather than array subscripts, but for
some processors the reverse is true.

==========

[Q20.20 Why don't C comments nest? ...]

Note also that // comments, as in C++, are not yet legal in C,
so it's not a good idea to use them in C programs (even if your
compiler supports them as an extension).
---
Note also that // comments have only become legal in C as of
C99.

==========

20.20b: Is C a great language, or what? Where else could you write
---
20.21b: Is C a great language, or what? Where else could you write
something like a+++++b ?

==========

[Q20.27 ... Can I use a C++ compiler to compile C code?]

compilation modes. See also questions 8.9 and 20.20.
---
compilation modes. (But it's usually a bad idea to compile
straight C code as if it were C++; the languages are different
enough that you'll generally get poor results.) See also
questions 8.9 and 20.20.

==========

20.32: Will 2000 be a leap year? Is (year % 4 == 0) an accurate test
for leap years?
---
20.32: Is (year % 4 == 0) an accurate test for leap years? (Was 2000 a
leap year?)

A: Yes and no, respectively. The full expression for the present
Gregorian calendar is
---
A: No, it's not accurate (and yes, 2000 was a leap year).
The full expression for the present Gregorian calendar is

==========

[Q20.34 ...how do you write a program which produces its own source code...?]

(This program, like many of the genre, neglects to #include
stdio.h, and assumes that the double-quote character " has the
---
(This program has a few deficiencies, among other things
neglecting to #include stdio.h, and assuming that the double-
quote character " has the value 34, as it does in ASCII.)

Here is an improved version, posted by James Hu:

#define q(k)main(){return!puts(#k"\nq("#k")");}
q(#define q(k)main(){return!puts(#k"\nq("#k")");})

==========

[Q20.35 What is "Duff's Device"?]

A: It's a devastatingly deviously unrolled byte-copying loop,
devised by Tom Duff while he was at Lucasfilm. In its "classic"
form, it looks like:
---
A: It's a devastatingly devious way of unrolling a loop, devised by
Tom Duff while he was at Lucasfilm. In its "classic" form, it
was used to copy bytes, and looked like this:

==========

[Q20.38 Where does the name "C" come from, anyway?]

A: C was derived from Ken Thompson's experimental language B, which
was inspired by Martin Richards's BCPL (Basic Combined
Programming Language), which was a simplification of CPL
(Cambridge Programming Language).
---
(Combined Programming Language, or perhaps Cambridge Programming
Language).

==========

[Q20.40 Where can I get extra copies of this list?]

What about back issues?

This list is an evolving document containing questions which
have been Frequent since before the Great Renaming; it is not
just a collection of this month's interesting questions. Older
copies are obsolete and don't contain much, except the
occasional typo, that the current list doesn't.

C Interview Questions - Part 3

[Q2.14 How can I determine the byte offset of a field within a structure?]

A: ANSI C defines the offsetof() macro, which should be used if
available; see stddef.h. If you don't have it, one possible
implementation is
---
A: ANSI C defines the offsetof() macro in stddef.h, which lets
you compute the offset of field f in struct s as
offsetof(struct s, f). If for some reason you have to code this
sort of thing yourself, one possibility is

==========

[2.15 How can I access structure fields by name at run time?]

A: Build a table of names and offsets, using the offsetof() macro.
The offset of field b in struct a is

offsetb = offsetof(struct a, b)

If structp is a pointer to an instance of this structure, and
field b is an int (with offset as computed above), b's value can
be set indirectly with
---
A: Keep track of the field offsets as computed using the offsetof()
macro (see question 2.14). If structp is a pointer to an
instance of the structure, and field f is an int having offset
offsetf, f's value can be set indirectly with

==========

[Q2.20 Can I initialize unions?]

A: The current C Standard allows an initializer for the first-named
member of a union. C9X will introduce "designated initializers"
which can be used to initialize any member.
---
A: In the original ANSI C, an initializer was allowed only for the
first-named member of a union. C99 introduces "designated
initializers" which can be used to initialize any member.

==========

[Q3.2 Under my compiler... Regardless of the order of evaluation...]

example, the compiler chose to multiply the previous value by
itself and to perform both increments afterwards.
---
itself and to perform both increments later.

[Q3.8 How can I understand these complex expressions?]

The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.
---
and all accesses to it within the same expression must be
directly involved in the computation of the value to be written.
This rule effectively constrains legal expressions to those in
which the accesses demonstrably precede the modification. For
example, i = i + 1 is legal, but not a[i] = i++ (see question
3.1).

==========

[3.9 So... we don't know which..., but i does get incremented..., right?]

A: *No*. Once an expression or program becomes undefined, *all*
---
A: Not necessarily! Once an expression or program becomes
undefined, *all* aspects of it become undefined.

==========

[Q4.2 I'm trying to declare a pointer and allocate some space for it...]

A: The pointer you declared is p, not *p. To make a pointer point
somewhere, you just use the name of the pointer:
---
A: The pointer you declared is p, not *p. When you're manipulating
the pointer itself (for example when you're setting it to make
it point somewhere), you just use the name of the pointer:

==========

[4.3 Does *p++ increment p, or what it points to?]

A: Postfix ++ essentially has higher precedence than the prefix
---
A: The postfix ++ and -- operators essentially have higher
precedence than the prefix unary operators.

==========

[Q4.10 ...How can I pass a constant by reference?]

A: You can't do this directly. You will have to declare
---
A: In C99, you can use a "compound literal":

f((int[]){5});

Prior to C99, you couldn't do this directly; you had to declare
a temporary variable, and then pass its address to the function:

==========

[Q5.6 If NULL were defined as follows...]

At any rate, ANSI function prototypes ensure that most (though
not quite all; see question 5.2) pointer arguments are converted
correctly when passed as function arguments, so the question is
largely moot.

==========

5.20: What does a run-time "null pointer assignment" error mean?
How can I track it down?

A debugger may let you set a data watchpoint on location 0.
Alternatively, you could write a bit of code to stash away a
copy of 20 or so bytes from location 0, and periodically check
that the memory at location 0 hasn't changed. See also question
16.8.

==========

[Q6.15 How can I declare local arrays of a size matching a passed-in array?]

A: Until recently, you couldn't. Array dimensions in C
traditionally had to be compile-time constants. C9X will
introduce variable-length arrays (VLA's) which will solve this
---
A: Until recently, you couldn't; array dimensions in C
traditionally had to be compile-time constants. However, C99
introduces variable-length arrays (VLA's) which solve this
problem; local arrays may have sizes set by variables or other
expressions, perhaps involving function parameters.

==========

[Q6.16 How can I dynamically allocate a multidimensional array?]

You can also use sizeof(*array1) and sizeof(**array1)
instead of sizeof(int *) and sizeof(int).)

==========

[Q6.19 How do I write functions which accept two-dimensional arrays...]

C9X will allow variable-length arrays, and once compilers which
accept C9X's extensions become widespread, this will probably
---
C99 allows variable-length arrays, and once compilers which
accept C99's extensions become widespread, VLA's will probably
become the preferred solution.

==========

[Q7.27 So can I query the malloc package to find out how big...]

(Some compilers provide nonstandard extensions.)

==========

[Q7.32 What is alloca() and why is its use discouraged?]

Now that C99 supports variable-length arrays (VLA's),
they can be used to more cleanly accomplish most of the
tasks which alloca() used to be put to.

==========

[Q8.6 How can I get the numeric (character set) value corresponding to...]

To convert back and forth between the digit characters and the
corresponding integers in the range 0-9, add or subtract the
constant '0' (that is, the character value '0').

==========

[Q10.7 Is it acceptable for one header file to #include another?]

the prestigious Indian Hill Style Guide (see question 17.9)
disparages them; they can make it harder to find relevant
definitions; they can lead to multiple-definition errors if a file
is #included twice;
---
is #included twice; they can lead to increased compilation time;
and they make manual Makefile maintenance very difficult.

==========

10.11: I seem to be missing the system header file sgtty.h.
Can someone send me a copy?
---
10.11: I'm compiling a program, and I seem to be missing one of the
header files it requires. Can someone send me a copy?

A: There are several situations, depending on what sort of header
file it is that's "missing".

If the missing header file is a standard one, there's a problem
with your compiler. You'll need to contact your vendor, or
someone knowledgeable about your particular compiler, for help.

The situation is more complicated in the case of nonstandard
headers. Some are completely system- or compiler-specific.
Some are completely unnecessary, and should be replaced by their
Standard equivalents. (For example, instead of malloc.h, use
stdlib.h.) Other headers, such as those associated with
popular add-on libraries, may be reasonably portable.

Standard headers exist in part so that definitions appropriate
to your compiler, operating system, and processor can be
supplied. You cannot just pick up a copy of someone else's
header file and expect it to work, unless that person is using
exactly the same environment. Ask your compiler vendor why the
file was not provided (or to send a replacement copy).
---
exactly the same environment. You may actually have a
portability problem (see section 19), or a compiler problem.
Otherwise, see question 18.16.

==========

[Q10.26 How can I write a macro which takes a variable number of arguments?]

C9X will introduce formal support for function-like macros with
variable-length argument lists. The notation ... will appear at
---
C99 introduces formal support for function-like macros with
variable-length argument lists. The notation ... can appear at

definition will be replaced by the variable arguments during
---
definition is replaced by the variable arguments during

==========

[Q11.1 What is the "ANSI C Standard?"]

More recently, the Standard has been adopted as an international
standard, ISO/IEC 9899:1990, and this ISO Standard replaces the
earlier X3.159 even within the United States (where it is known
---
A year or so later, the Standard was adopted as an international
standard, ISO/IEC 9899:1990, and this ISO Standard replaced the
earlier X3.159 even within the United States (where it was known

As of this writing, a complete revision of the Standard is in
its final stages. The new Standard is nicknamed "C9X" on the
assumption that it will be finished by the end of 1999. (Many
of this article's answers have been updated to reflect new C9X
features.)
---
Most recently, a major revision of the Standard, "C99", has been
completed and adopted.

The original ANSI Standard included a "Rationale," explaining
many of its decisions, and discussing a number of subtle points,
including several of those covered here. (The Rationale was
"not part of ANSI Standard X3.159-1989, but... included for
information only," and is not included with the ISO Standard.
A new one is being prepared for C9X.)
---
Several versions of the Standard, including C99 and the original
ANSI Standard, have included a "Rationale," explaining many of
its decisions, and discussing a number of subtle points,
including several of those covered here.

==========

[Q11.2 How can I get a copy of the Standard?]

Note that ANSI derives revenues to support its operations
from the sale of printed standards, so electronic copies
are *not* available.
---
An electronic (PDF) copy is available on-line, for US$18,
from www.ansi.org.

The last time I checked, the cost was $130.00 from ANSI or
$400.50 from Global. Copies of the original X3.159 (including
the Rationale) may still be available at $205.00 from ANSI or
$162.50 from Global.

In the U.S., it may be possible to get a copy of the original
ANSI X3.159 (including the Rationale) as "FIPS PUB 160" from

National Technical Information Service (NTIS)
U.S. Department of Commerce
Springfield, VA 22161
703 487 4650

==========

[Q11.10 Why can't I pass a char ** to a function which expects...]

You must use explicit casts (e.g. (const char **) in this case)
when assigning (or passing) pointers which have qualifier
mismatches at other than the first level of indirection.
---
If you must assign or pass pointers which have qualifier
mismatches at other than the first level of indirection, you
must use explicit casts (e.g. (const char **) in this case),
although as always, the need for such a cast may indicate a
deeper problem which the cast doesn't really fix.

==========

11.27: Why does the ANSI Standard not guarantee more than six case-
insensitive characters of external identifier significance?
---
11.27: Why does the ANSI Standard place limits on the length and case-
significance of external identifiers?

The limitation is only that identifiers be *significant*
in the first six characters, not that they be restricted to
six characters in length. This limitation is marked in the
Standard as "obsolescent", and will be removed in C9X.
---
in some initial sequence of characters, not that they be
restricted to that many characters in total length.
(The limitation was to six characters in the original
ANSI Standard, but has been relaxed to 31 in C99.)

==========

[Q11.33 ...implementation-defined, unspecified, and undefined behavior.]

(A fourth defined class of not-quite-precisely-defined behavior,
without the same stigma attached to it, is "locale-specific".)

==========

[Q12.2 Why does the code... copy the last line twice?]

Usually, you should just check the return value of
the input routine (in this case, fgets() will return NULL on end-
of-file); often, you don't need to use feof() at all.
---
the input routine -- fgets(), for example, returns NULL on end-
of-file. In virtually all cases, there's no need to use feof()
at all.

==========

[Q12.21 How can I tell how much... buffer space... for a... sprintf call?]

The "obvious" solution to the overflow problem is a length-
limited version of sprintf(), namely snprintf(). It would be
used like this:
---
To avoid the overflow problem, you can use a length-limited
version of sprintf(), namely snprintf(). It is used like this:

It will be standardized in C9X.
---
It has finally been standardized in C99.

When the C9X snprintf() arrives, it will also be possible to use
it to predict the size required for an arbitrary sprintf() call.
C9X snprintf() will return the number of characters it would
have placed in the buffer, not just how many it did place.
Furthermore, it may be called with a buffer size of 0 and a
null pointer as the destination buffer. Therefore, the call
---
As an extra, added bonus, the C99 snprintf() provides a way
to predict the size required for an arbitrary sprintf() call.
C99's snprintf() returns the number of characters it would have
placed in the buffer, and it may be called with a buffer size
of 0. Therefore, the call

will compute the number of characters required for the fully-
---
predicts the number of characters required for the fully-

Yet another option is the (nonstandard) asprintf() function,
present in various C libraries including bsd's and GNU's, which
formats to (and returns a pointer to) a malloc'ed buffer, like
this:

char *buf;
asprintf(&buf, "%d = %s", 42, "forty-two");
/* now buf points to malloc'ed space containing formatted string */

==========

[Q12.23 Why does everyone say not to use gets()?]

A: Unlike fgets(), gets() cannot be told the size of the buffer
it's to read into, so it cannot be prevented from overflowing
that buffer. As a general rule, always use fgets().
---
that buffer. The Standard fgets() function is a vast
improvement over gets(), although it's not perfect, either.
(If long lines are a real possibility, their proper handling
must be carefully considered.)

==========

12.26: How can I flush pending input so that a user's typeahead isn't
---
12.26b: If fflush() won't work, what can I use to flush input?

There is no standard way to discard unread characters from a
stdio input stream, nor would such a way necessarily be
sufficient, since unread characters can also accumulate in
other, OS-level input buffers. You may be able to read and
discard characters until \n, or use the curses flushinp()
function, or use some system-specific technique. See also
questions 19.1 and 19.2.
---
other, OS-level input buffers. If you're trying to actively
discard typed-ahead input (perhaps in anticipation of issuing a
critical prompt), you'll have to use a system-specific
technique; see questions 19.1 and 19.2.

==========

[Q12.30 I'm trying to update a file in place...]

writing in the read/write "+" modes. Also, remember that you
can only overwrite characters with the same number of
replacement characters, and that overwriting in text mode may
truncate the file at that point. See also question 19.14.
---
truncate the file at that point, and that you may have to
preserve line lengths. See also question 19.14.

==========

[Q12.34 Once I've used freopen(), how can I get the original stdout... back?]

It is barely possible to save away information about a stream
before calling freopen(), such that the original stream can
later be restored, but the methods involve system-specific calls
such as dup(), or copying or inspecting the contents of a FILE
structure, which is exceedingly nonportable and unreliable.
---
It may be possible, in a nonportable way, to save away
information about a stream before calling freopen(), such that
the original stream can later be restored. One way is to use a
system-specific call such as dup() or dup2(), if available.
Another is to copy or inspect the contents of the FILE
structure, but this is exceedingly nonportable and unreliable.

==========

12.36b: How can I arrange to have output go two places at once,
e.g. to the screen and to a file?

Here is a simple example:

#include stdio.h
#include stdarg.h

void f2printf(FILE *fp1, FILE *fp2, char *fmt, ...)
{
va_list argp;
va_start(argp, fmt); vfprintf(fp1, fmt, argp); va_end(argp);
va_start(argp, fmt); vfprintf(fp2, fmt, argp); va_end(argp);
}

where f2printf() is just like fprintf() except that you give it
two file pointers and it prints to both of them.

==========

[Q13.2 Why does strncpy() not always place a '\0' terminator...]

You can get around the problem by using strncat() instead
of strncpy(): if the destination string starts out empty
(that is, if you do *dest = '\0' first), strncat()
does what you probably wanted strncpy() to do.

==========

[Q13.12 How can I get the current date or time of day in a C program?]

printf("It's %.24s.\n", ctime(&now));
---
printf("It's %s", ctime(&now));

If you need control over the format, use strftime().
If you need sub-second resolution, see question 19.37.

==========

[Q13.14 How can I add N days to a date?]

A: The ANSI/ISO Standard C mktime() and difftime() functions
provide some support for both problems.
---
provide some (limited) support for both problems.

These solutions are only guaranteed to work correctly
---
However, these solutions are guaranteed to work correctly only
for dates in the range which can be represented as time_t's.

(For conservatively-sized time_t, that range is often -- but not
always -- from 1970 to approximately 2037; note however that
there are time_t representations other than as specified by Unix
and Posix.)

Another approach to both problems,
which will work over a much wider range of dates,
is to use "Julian day numbers".

==========

[Q13.15 I need a random number generator.]

If you do find yourself needing to implement your own random
number generator, there is plenty of literature out there; see
the References. There are also any number of packages on the
net: look for r250, RANLIB, and FSULTRA (see question 18.16).
---
the References below or the sci.math.num-analysis FAQ list.
There are also any number of packages on the net: old standbys
are r250, RANLIB, and FSULTRA (see question 18.16), and there is
much recent work by Marsaglia, and Matumoto and Nishimura (the
"Mersenne Twister"), and some code collected by Don Knuth on his
web pages.

==========

[Q13.17 Each time I run my program, I get the same sequence of numbers...]

A: You can call srand() to seed the pseudo-random number generator
with a truly random initial value. Popular seed values are the
time of day, or the elapsed time before the user presses a key
(although keypress times are hard to determine portably;
---
with a truly random (or at least variable) initial value, such
as the time of day. Here is a simple example:

#include stdlib.h
#include time.h

srand((unsigned int)time((time_t *)NULL));

(Unfortunately, this code isn't perfect -- among other things,
the time_t returned by time() might be a floating-point type,
hence not portably convertible to unsigned int without the
possibility of overflow.

==========

[Q14.1 When I set a float... 3.1, why is printf printing it as 3.0999999?]

A: Most computers use base 2 for floating-point numbers as well as
for integers. In base 2, one divided by ten is an infinitely-
repeating fraction (0.0001100110011...), so fractions such as
3.1 (which look like they can be exactly represented in decimal)
---
for integers. Although 0.1 is a nice, polite-looking fraction
in base 10, its base-2 representation is an infinitely-repeating
fraction (0.0001100110011...), so exact decimal fractions such as 3.1
cannot be represented exactly in binary.

[Q14.3 ...I keep getting "undefined: sin" compilation errors.]

A: Make sure you're actually linking with the math library. For
instance, under Unix, you usually need to use the -lm option, at
---
instance, due to a longstanding bug in Unix and Linux systems,
you usually need to use an explicit -lm flag, at the *end* of
the command line, when compiling/linking.

==========

[Q14.5 What's a good way to check for "close enough" floating-point equality?]

use something like

#include math.h
if(fabs(a - b) = epsilon * fabs(a))

for some suitably-chosen degree of closeness epsilon (as long as
a is nonzero!).
---
where epsilon is a value chosen to set the degree of "closeness"
(and where you know that a will not be zero).

==========

[Q14.8 The predefined constant M_PI seems to be missing...]
machine's copy of math.h.

If you need pi, you'll have to define it yourself, or compute it
with 4*atan(1.0).
---
with 4*atan(1.0) or acos(-1.0).

==========

[Q14.9 How do I test for IEEE NaN and other special values?]

C9X will provide isnan(), fpclassify(), and several other
---
C99 provides isnan(), fpclassify(), and several other
classification routines.

==========

[Q14.11 What's a good way to implement complex numbers in C?]

C9X will support complex as a standard type.
---
C99 supports complex as a standard type.

==========

[Q15.6 How can I write a function analogous to scanf()...]

A: C9X will support vscanf(), vfscanf(), and vsscanf().
(Until then, you may be on your own.)
---
A: C99 (but *not* any earlier C Standard) supports vscanf(),
vfscanf(), and vsscanf().

==========

[Q16.1b I'm getting baffling syntax errors which make no sense at all...]

A: Check for unclosed comments or mismatched #if/#ifdef/#ifndef/
#else/#endif directives; remember to check header files, too.
---
A: Check for unclosed comments, mismatched #if/#ifdef/#ifndef/
#else/#endif directives, and perhaps unclosed quotes; remember
to check header files, too.

C Interview Questions - Part 2

2.4b: Is there a good way of simulating OOP-style inheritance, or
other OOP features, in C?

A: It's straightforward to implement simple "methods" by placing
function pointers in structures. You can make various clumsy,
brute-force attempts at inheritance using the preprocessor or by
having structures contain "base types" as initial subsets, but
it won't be perfect. There's obviously no operator overloading,
and overriding (i.e. of "methods" in "derived classes") would
have to be done by hand.

Obviously, if you need "real" OOP, you'll want to use a language
that supports it, such as C++.

==========

3.12a: What's the difference between ++i and i++?

A: If your C book doesn't explain, get a better one. Briefly:
++i adds one to the stored value of i and "returns" the new,
incremented value to the surrounding expression; i++ adds one
to i but returns the prior, unincremented value.

==========

4.15: How do I convert an int to a char *? I tried a cast, but it's
not working.

A: It depends on what you're trying to do. If you tried a cast
but it's not working, you're probably trying to convert an
integer to a string, in which case see question 13.1. If you're
trying to convert an integer to a character, see question 8.6.
If you're trying to set a pointer to point to a particular
memory address, see question 19.25.

==========

7.7c: In a call to malloc(), what does an error like "Cannot convert
`void *' to `int *'" mean?

A: It means you're using a C++ compiler instead of a C compiler.
See question 7.7.

==========

7.11: How can I dynamically allocate arrays?

A: See questions 6.14 and 6.16.

==========

11.8b: If you can't modify string literals, why aren't they defined as
being arrays of const characters?

A: One reason is that so very much code contains lines like

char *p = "Hello, world!";

which are not necessarily incorrect. These lines would suffer
the diagnostic messages, but it's really any later attempt to
modify what p points to which would be problems.

See also question 1.32.

==========

11.14b: So what could go wrong? Are there really any systems where
void main() doesn't work?

A: It has been reported that programs using void main() and
compiled using BC++ 4.5 can crash. Some compilers (including
DEC C V4.1 and gcc with certain warnings enabled) will complain
about void main().

==========

11.33b: What does it really mean for a program to be "legal" or "valid"
or "conforming"?

A: Simply stated, the Standard talks about three kinds of
conformance: conforming programs, strictly conforming programs,
and conforming implementations.

A "conforming program" is one that is accepted by a conforming
implementation.

A "strictly conforming program" is one that uses the language
exactly as specified in the Standard, and that does not depend
on any implementation-defined, unspecified, or undefined
behavior.

A "conforming implementation" is one that does everything the
Standard says it's supposed to.

References: ISO Sec. ; Rationale Sec. 1.7.

==========

12.1b: I have a simple little program that reads characters until EOF,
but how do I actually *enter* that "EOF" value from the
keyboard?

A: It turns out that the value of EOF as seen within your C program
has essentially nothing to do with the keystroke combination you
might use to signal end-of-file from the keyboard. Depending on
your operating system, you indicate end-of-file from the
keyboard using various keystroke combinations, usually either
control-D or control-Z.

==========

12.12b: Why *does* the call

char s[30];
scanf("%s", s);

work (without the &)?

A: You always need a *pointer*; you don't necessarily need an
explicit &. When you pass an array to scanf(), you do not need
the &, because arrays are always passed to functions as
pointers, whether you use & or not. See questions 6.3 and 6.4.

==========

12.26b: If fflush() won't work, what can I use to flush input?

A: It depends on what you're trying to do. If you're trying to get
rid of an unread newline or other unexpected input after calling
scanf() (see questions 12.18a-12.19), you really need to rewrite
or replace the call to scanf() (see question 12.20).
Alternatively, you can consume the rest of a partially-read line
with a simple code fragment like

while((c = getchar()) != '\n' && c != EOF)
/* discard */ ;

(You may also be able to use the curses flushinp() function.)

==========

12.27: fopen() is failing for certain pathnames.

A: See questions 19.17 and 19.17b.

==========

13.29: My compiler is complaining that printf is undefined!
How can this be?

A: Allegedly, there are C compilers for Microsoft Windows which do
not support printf(). It may be possible to convince such a
compiler that what you are writing is a "console application"
meaning that it will open a "console window" in which printf()
is supported.

==========

17.4b: I've seen function declarations that look like this:

extern int func __((int, int));

What are those extra parentheses and underscores for?

A: They're part of a trick which allows the prototype part of the
function declaration to be turned off for a pre-ANSI compiler.
Somewhere else is a conditional definition of the __ macro like
this:

#ifdef __STDC__
#define __(proto) proto
#else
#define __(proto) ()
#endif

The extra parentheses in the invocation

extern int func __((int, int));

are required so that the entire prototype list (perhaps
containing many commas) is treated as the single argument
expected by the macro.

==========

18.9b: Where can I find some good code examples to study and learn
from?

A: Here are a couple of links to explore:

ftp://garbo.uwasa.fi/pc/c-lang/00index.txt

http://www.eskimo.com/~scs/src/

(Beware, though, that there is all too much truly bletcherous
code out there, too. Don't "learn" from bad code that it's the
best anyone can do; you can do better.) See also questions
18.9, 18.13, 18.15c, and 18.16.

==========

19.9b: How can I access an I/O board directly?

A: In general, there are two ways to do this: use system-specific
functions such as "inport" and "outport" (if the device is
accessed via an "I/O port"), or use contrived pointer variables
to access "memory-mapped I/O" device locations. See question
19.25.

==========

19.10b: How can I display GIF and JPEG images?

A: It will depend on your display environment, which may already
provide these functions. Reference JPEG software is at
http://www.ijg.org/files/ .

==========

19.17b: fopen() isn't letting me open files like "$HOME/.profile" and
"~/.myrcfile".

A: Under Unix, at least, environment variables like $HOME, along
with the home-directory notation involving the ~ character, are
expanded by the shell, and there's no mechanism to perform these
expansions automatically when you call fopen().

==========

19.17c: How can I suppress the dreaded MS-DOS "Abort, Retry, Ignore?"
message?

A: Among other things, you need to intercept the DOS Critical Error
Interrupt, interrupt 24H. See the comp.os.msdos.programmer FAQ
list for more details.

==========

19.40d: What are "near" and "far" pointers?

A: These days, they're pretty much obsolete; they're definitely
system-specific. If you really need to know, see a DOS- or
Windows-specific programming reference.

==========

20.9b: How do I swap bytes?

A: V7 Unix had a swab() function, but it seems to have been
forgotten.

A problem with explicit byte-swapping code is that you have
to decide whether to call it or not; see question 20.9 above.
A better solution is to use functions (such as the BSD
networking ntohs() et al.) which convert between the known byte
order of the data and the (unknown) byte order of the machine,
and to arrange for these functions to be no-ops on those
machines which already match the desired byte order.

If you do have to write your own byte-swapping code, the two
obvious approaches are again to use pointers or unions, as in
question 20.9.

References: PCS Sec. 11 p. 179.

====================


Next, here are the significant changes.

==========

[Q1.1 How should I decide which integer type to use?]

If for some reason you need to declare something with an
*exact* size... be sure to encapsulate the choice behind
an appropriate typedef.
---
an appropriate typedef, such as those in C99's inttypes.h.

If you need to manipulate huge values, larger than the
guaranteed range of C's built-in types, see question 18.15d.

==========

[Q1.4 What should the 64-bit type be on a machine that can support it?]

A: The forthcoming revision to the C Standard (C9X) specifies type
long long as effectively being at least 64 bits, and this type
has been implemented by a number of compilers for some time.
(Others have implemented extensions such as __longlong.)
On the other hand, there's no theoretical reason why a compiler
couldn't implement type short int as 16, int as 32, and long int
as 64 bits, and some compilers do indeed choose this
arrangement.
---
A: The new C99 Standard specifies type long long as effectively
being at least 64 bits, and this type has been implemented by a
number of compilers for some time. (Others have implemented
extensions such as __longlong.) On the other hand, it's also
appropriate to implement type short int as 16, int as 32, and
long int as 64 bits, and some compilers do.

==========

[Q1.7 What's the best way to declare and define global variables...]

A: First, though there can be many "declarations" (and in many
translation units) of a single "global" (strictly speaking,
"external") variable or function, there must be exactly one
"definition". (The definition is the declaration that actually
allocates space, and provides an initialization value, if any.)
---
translation units) of a single global variable or function,
there must be exactly one "definition", where the definition is
the declaration that actually allocates space, and provides an
initialization value, if any.

==========

(Unix compilers and linkers typically use a "common model" which
allows multiple definitions, as long as at most one is
initialized; this behavior is mentioned as a "common extension"
by the ANSI Standard, no pun intended. A few very odd systems
may require an explicit initializer to distinguish a definition
from an external declaration.)
---
by the ANSI Standard, no pun intended.)

==========

[Q1.25 My compiler is complaining about an invalid redeclaration...]

A: Functions which are called without a declaration in scope
(perhaps because the first call precedes the function's
definition) are assumed to be declared as returning int (and
without any argument type information), leading to discrepancies
if the function is later declared or defined otherwise. Non-int
functions must be declared before they are called.
---
A: Functions which are called without a declaration in scope,
perhaps because the first call precedes the function's
definition, are assumed to be declared as returning int (and
without any argument type information), leading to discrepancies
if the function is later declared or defined otherwise. All
functions should be (and non-int functions must be) declared
before they are called.

==========

[Q1.30 What am I allowed to assume about the initial values...]

These rules do apply to arrays and structures (termed
"aggregates"); arrays and structures are considered "variables"
as far as initialization is concerned.

==========

[Q1.31 This code, straight out of a book, isn't compiling]

A: Perhaps you have a pre-ANSI compiler, which doesn't allow
initialization of "automatic aggregates" (i.e. non-static
local arrays, structures, and unions). (As a workaround, and
depending on how the variable a is used, you may be able to make
it global or static, or replace it with a pointer, or initialize
it by hand with strcpy() when f() is called.)
---
A: Perhaps you have an old, pre-ANSI compiler, which doesn't allow
initialization of "automatic aggregates" (i.e. non-static local
arrays, structures, or unions).

==========

[Q1.34 I finally figured out the syntax for... pointers to functions...]

An explicit declaration for the function is normally needed,
since implicit external function declaration does not happen in
this case (because the function name in the initialization is
not part of a function call).
---
A prior, explicit declaration for the function (perhaps in a
header file) is normally needed. The implicit external function
declaration that can occur when a function is called does not
help when a function name's only use is for its value.

==========

[Q2.4 How can I implement opaque (abstract) data types in C?]

A: One good way is for clients to use structure pointers (perhaps
additionally hidden behind typedefs) which point to structure
types which are not publicly defined. It's legal to declare
and use "anonymous" structure pointers (that is, pointers to
structures of incomplete type), as long as no attempt is made to
access the members -- which of course is exactly the point of an
opaque type.

==========

[Q2.6 I came across some code that declared a structure like this...]

these "chummy" structures must be used with care, since the
programmer knows more about their size than the compiler does.
(In particular, they can generally only be manipulated via
pointers.)

C9X will introduce the concept of a "flexible array member",
which will allow the size of an array to be omitted if it is
the last member in a structure, thus providing a well-defined
solution.
---
C99 introduces the concept of a "flexible array member", which
allows the size of an array to be omitted if it is the last
member in a structure, thus providing a well-defined solution.

==========

[Q2.10 How can I pass constant... structure arguments?]

A: As of this writing, C has no way of generating anonymous
structure values. You will have to use a temporary structure
variable or a little structure-building function.
---
A: Traditional C had no way of generating anonymous structure
values; you had to use a temporary structure variable or a
little structure-building function.

The C9X Standard will introduce "compound literals"; one form of
compound literal will allow structure constants. For example,
to pass a constant coordinate pair to a plotpoint() function
which expects a struct point, you will be able to call
---
C99 introduces "compound literals", one form of which provides
for structure constants. For example, to pass a constant
coordinate pair to a hypothetical plotpoint() function which
expects a struct point, you can call

Combined with "designated initializers" (another C9X feature),
it will also be possible to specify member values by name:
---
Combined with "designated initializers" (another C99 feature),
it is also possible to specify member values by name:

==========

2.12: My compiler is leaving holes in structures, which is wasting
space and preventing "binary" I/O to external data files. Can I
turn off the padding, or otherwise control the alignment of
---
space and preventing "binary" I/O to external data files. Why?
Can I turn this off, or otherwise control the alignment of

A: Your compiler may provide an extension to give you this control
(perhaps a #pragma; see question 11.20), but there is no
standard method.
---
A: Those "holes" provide "padding", which may be needed in order to
preserve the "alignment" of later fields of the structure. For
efficient access, most processors prefer (or require) that
multibyte objects (e.g. structure members of any type larger
than char) not sit at arbitrary memory addresses, but rather at
addresses which are multiples of 2 or 4 or the object size.

Your compiler may provide an extension to give you explicit
control over struct alignment (perhaps involving a #pragma; see
question 11.20), but there is no standard method.

C interview Questions - Part 1


Section 1. Declarations and Initializations

1: What does extern mean in a function declaration?

A: Nothing, really; the keyword extern is optional here.

2: What's the auto keyword good for?

A: Nothing.

3: I can't seem to define a linked list node which contains a
pointer to itself.

A: Structures in C can certainly contain pointers to themselves;
the discussion and example in section 6.5 of K&R make this
clear. Problems arise if an attempt is made to define (and use)
a typedef in the midst of such a declaration; avoid this.

4: How do I declare an array of N pointers to functions returning
pointers to functions returning pointers to characters?

A: char *(*(*a[N])())();
Using a chain of typedefs, or the cdecl program, makes these
declarations easier.
5: What am I allowed to assume about the initial values
of variables which are not explicitly initialized?

A: Uninitialized variables with "static" duration start out as 0,
as if the programmer had initialized them. Variables with
"automatic" duration, and dynamically-allocated memory, start
out containing garbage (with the exception of calloc).

6: How can I declare a function that returns a pointer to a
function of its own type?

A: You can't quite do it directly. Use a cast, or wrap a struct
around the pointer and return that.

7: My compiler is complaining about an invalid redeclaration of a
function, but I only define it once.

A: Calling an undeclared function declares it implicitly as
returning int.

8: What's the right declaration for main()?

A: See questions 11.12a to 11.15.

9: How do you decide which integer type to use?

A: If you might need large values (tens of thousands), use long.
Otherwise, if space is very important, use short. Otherwise,
use int.

10: What should the 64-bit type on a machine that can support it?

A: C9X specifies long long.

11: What's the best way to declare and define global variables?

A: The best arrangement is to place each definition in some
relevant .c file, with an external declaration in a header file.


12: Why can't I initialize a local array with a string?

A: Perhaps you have a pre-ANSI compiler.

13: What's wrong with "char *p = malloc(10);" ?

A: Function calls are not allowed in initializers for global or
static variables.

14: How do I initialize a pointer to a function?

A: Use something like "extern int func(); int (*fp)() = func;" .

15: What is the difference between char a[] = "string"; and
char *p = "string"; ?

A: The first declares an initialized and modifiable array; the
second declares a pointer initialized to a not-necessarily-
modifiable constant string.

Section 2. Structures, Unions, and Enumerations


16: Why doesn't "struct x { ... }; x thestruct;" work?

A: C is not C++.

17: Can a structure contain a pointer to itself?

A: See question 1.14.

18: What's the difference between struct x1 { ... }; and
typedef struct { ... } x2; ?

A: The first structure is named by a tag, the second by a typedef
name.

19: Can I pass constant values to functions which accept structure
arguments?

A: Not yet. As of this writing, C has no way of generating
anonymous structure values.


20: What's the best way of implementing opaque (abstract) data types
in C?

A: One good way is to use structure pointers which point to
structure types which are not publicly defined.

21: How can I read/write structures from/to data files?

A: It is relatively straightforward to use fread and fwrite.

22: I came across some code that declared a structure with the last
member an array of one element, and then did some tricky
allocation to make it act like the array had several elements.
Is this legal or portable?

A: An official interpretation has deemed that it is not strictly
conforming with the C Standard.

23: Is there a way to compare structures automatically?

A: No.

24: I heard that structures could be assigned to variables and
passed to and from functions, but K&R1 says not.

A: These operations are supported by all modern compilers.

25: Why does sizeof report a larger size than I expect for a
structure type?

A: The alignment of arrays of structures must be preserved.

26: How can I turn off structure padding?

A: There is no standard method.

A: Build a table of names and offsets, using the offsetof() macro.

27: I have a program which works correctly, but dumps core after it
finishes. Why?

A: Check to see if a structure type declaration just before main()
is missing its trailing semicolon, causing main() to be declared
as returning a structure. See also questions 10.9 and 16.4.

28: Can I initialize unions?

A: The current C Standard allows an initializer for the first-named
member.

29: What is the difference between an enumeration and a set of
preprocessor #defines?

A: At the present time, there is little difference. The C Standard
states that enumerations are compatible with integral types.

30: Is there an easy way to print enumeration values symbolically?

A: No.

31: How can I determine the byte offset of a field within a
structure?

A: ANSI C defines the offsetof() macro, which should be used if
available.

32: How can I access structure fields by name at run time?


Section 3. Expressions

33: What should the code "int i = 3; i = i++;" do?

A: The expression is undefined.

34: Under my compiler, the code "int i = 7;
printf("%d\n", i++ * i++);" prints 49. Regardless of the order
of evaluation, shouldn't it print 56?

A: The operations implied by the postincrement and postdecrement
operators ++ and -- are performed at some time after the
operand's former values are yielded and before the end of the
expression, but not necessarily immediately after, or before
other parts of the expression are evaluated.

35: Here's a slick expression: "a ^= b ^= a ^= b". It swaps a and b
without using a temporary.

A: Not portably; its behavior is undefined.

36: Why doesn't the code "a[i] = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

37: Don't precedence and parentheses dictate order of evaluation?

A: Operator precedence and explicit parentheses impose only a
partial ordering on the evaluation of an expression, which does
not generally include the order of side effects.

38: But what about the && and || operators?

A: There is a special exception for those operators: left-to-right
evaluation is guaranteed.

39: What's a "sequence point"?

A: A point (at the end of a full expression, or at the ||, &&, ?:,
or comma operators, or just before a function call) at which all
side effects are guaranteed to be complete.

40: If I'm not using the value of the expression, should I use i++
or ++i to increment a variable?

A: Since the two forms differ only in the value yielded, they are
entirely equivalent when only their side effect is needed.

41: Why doesn't the code "int a = 1000, b = 1000;
long int c = a * b;" work?

A: You must manually cast one of the operands to (long).

42: So given a[i] = i++; we don't know which cell of a[] gets
written to, but i does get incremented by one, right?

A: *No*. Once an expression or program becomes undefined, *all*
aspects of it become undefined.

43: Can I use ?: on the left-hand side of an assignment expression?

A: No.


Section 4. Pointers

44: I want to use a char * pointer to step over some ints. Why
doesn't "((int *)p)++;" work?

A: In C, a cast operator is a conversion operator, and by
definition it yields an rvalue, which cannot be assigned to, or
incremented with ++.

45: I have a function which accepts, and is supposed to initialize,
a pointer, but the pointer in the caller remains unchanged.

A: The called function probably altered only the passed copy of the
pointer.

46: Can I use a void ** pointer as a parameter so that a function
can accept a generic pointer by reference?

A: Not portably.

47: What's wrong with "char *p; *p = malloc(10);"?

A: The pointer you declared is p, not *p.

48: Does *p++ increment p, or what it points to?

A: *p++ increments p. To increment the value pointed to by p, use
(*p)++ .

49: I have a function which accepts a pointer to an int. How can I
pass a constant like 5 to it?

A: You will have to declare a temporary variable.

50: I've seen different methods used for calling functions via
pointers.

A: The extra parentheses and explicit * are now officially
optional, although some older implementations require them.

51: Does C even have "pass by reference"?

A: Not really, though it can be simulated.

Section 5. Null Pointers

52: What is this infamous null pointer, anyway?

A: For each pointer type, there is a special value -- the "null
pointer" -- which is distinguishable from all other pointer
values and which is not the address of any object or function.
53: What is NULL and how is it #defined?

A: NULL is simply a preprocessor macro, #defined as 0 (or
((void *)0)), which is used (as a stylistic convention, in
preference to unadorned 0's) to generate null pointers.

54: Is the abbreviated pointer comparison "if(p)" to test for non-
null pointers valid?

A: Yes. The construction "if(p)" works, regardless of the internal
representation of null pointers, because the compiler
essentially rewrites it as "if(p != 0)" and goes on to convert 0
into the correct null pointer.


55: How do I get a null pointer in my programs?

A: A constant 0 in a pointer context is converted into a null
pointer at compile time. A "pointer context" is an
initialization, assignment, or comparison with one side a
variable or expression of pointer type, and (in ANSI standard C)
a function argument which has a prototype in scope declaring a
certain parameter as being of pointer type. In other contexts
(function arguments without prototypes, or in the variable part
of variadic function calls) a constant 0 with an appropriate
explicit cast is required.

56: How should NULL be defined on a machine which uses a nonzero bit
pattern as the internal representation of a null pointer?

A: The same as on any other machine: as 0. (The compiler makes the
translation, upon seeing a 0, not the preprocessor; )

57: But wouldn't it be better to use NULL, in case the value of NULL
changes?

A: No. NULL is a constant zero, so a constant zero is equally
sufficient.

58: If NULL and 0 are equivalent as null pointer constants, which
should I use?

A: Either; the distinction is entirely stylistic.

59: I use the preprocessor macro "#define Nullptr(type) (type *)0"
to help me build null pointers of the correct type.

A: This trick, though valid, does not buy much.

60: If NULL were defined as "((char *)0)," wouldn't that make
function calls which pass an uncast NULL work?

A: Not in general. The complication is that there are machines
which use different internal representations for pointers to
different types of data. A cast is still required to tell the
compiler which kind of null pointer is required, since it may be
different from (char *)0.

61: This is strange. NULL is guaranteed to be 0, but the null
pointer is not?

A: A "null pointer" is a language concept whose particular internal
value does not matter. A null pointer is requested in source
code with the character "0". "NULL" is a preprocessor macro,
which is always #defined as 0 (or ((void *)0)).

62: Given all the confusion surrounding null pointers, wouldn't it
be easier simply to require them to be represented internally by
zeroes?

A: Such a requirement would accomplish little.

63: Seriously, have any actual machines really used nonzero null
pointers?

A: Machines manufactured by Prime, Honeywell-Bull, and CDC, as well
as Symbolics Lisp Machines, have done so.

64: What does a run-time "null pointer assignment" error mean?

A: It means that you've written, via a null pointer, to an invalid
location. (See also question 16.8.)

65: Why is there so much confusion surrounding null pointers?

A: The fact that null pointers are represented both in source code,
and internally to most machines, as zero invites unwarranted
assumptions. The use of a preprocessor macro (NULL) may seem to
suggest that the value could change some day, or on some weird
machine.

66: I'm confused. I just can't understand all this null pointer
stuff.

A: A simple rule is, "Always use `0' or `NULL' for null pointers,
and always cast them when they are used as arguments in function
calls."

Section 6. Arrays and Pointers


67: Why are array and pointer declarations interchangeable as
function formal parameters?

A: It's supposed to be a convenience.

68: What is the real difference between arrays and pointers?

A: Arrays automatically allocate space which is fixed in size and
location; pointers are dynamic.

69: How can an array be an lvalue, if you can't assign to it?

A: An array is not a "modifiable lvalue."

70: I came across some "joke" code containing the "expression"
5["abcdef"] . How can this be legal C?

A: Yes, array subscripting is commutative in C. The array
subscripting operation a[e] is defined as being identical to
*((a)+(e)).

71: Someone explained to me that arrays were really just constant
pointers.

A: An array name is "constant" in that it cannot be assigned to,
but an array is *not* a pointer.

72: I had the definition char a[6] in one source file, and in
another I declared extern char *a. Why didn't it work?

A: The declaration extern char *a simply does not match the actual
definition. Use extern char a[].

73: How can I use statically- and dynamically-allocated
multidimensional arrays interchangeably when passing them to
functions?

A: There is no single perfect method, but see the full list for
some ideas.

74: Why doesn't sizeof properly report the size of an array which is
a parameter to a function?

A: The sizeof operator reports the size of the pointer parameter
which the function actually receives.


75: So what is meant by the "equivalence of pointers and arrays" in
C?

A: An lvalue of type array-of-T which appears in an expression
decays into a pointer to its first element; the type of the
resultant pointer is pointer-to-T. So for an array a and
pointer p, you can say "p = a;" and then p[3] and a[3] will
access the same element.

76: But I heard that char a[] was identical to char *a.

A: Not at all. Arrays are not pointers. A reference like x[3]
generates different code depending on whether x is an array or a
pointer.

77: What's the difference between array and &array?

A: The type.

78: How do I declare a pointer to an array?

A: Usually, you don't want to. Consider using a pointer to one of
the array's elements instead.

79: How can I set an array's size at run time?

A: It's straightforward to use malloc() and a pointer.

80: How can I declare local arrays of a size matching a passed-in
array?

A: Until recently, you couldn't; array dimensions had to be compile-
time constants. C9X will fix this.

81: How can I dynamically allocate a multidimensional array?

A: The traditional solution is to allocate an array of pointers,
and then initialize each pointer to a dynamically-allocated
"row." See the full list for code samples.

82: My compiler complained when I passed a two-dimensional array to
a function expecting a pointer to a pointer.

A: The rule by which arrays decay into pointers is not applied
recursively. An array of arrays (i.e. a two-dimensional array
in C) decays into a pointer to an array, not a pointer to a
pointer.

83: Can I simulate a non-0-based array with a pointer?

A: Not if the pointer points outside of the block of memory it is
intended to access.

84: How do I write functions which accept two-dimensional arrays
when the width is not known at compile time?

A: It's not always particularly easy.


Section 7. Memory Allocation


85: But the man page for strcat() says that it takes two char *'s as
arguments. How am I supposed to know to allocate things?

A: In general, when using pointers you *always* have to consider
memory allocation, if only to make sure that the compiler is
doing it for you.

86: I just tried the code "char *p; strcpy(p, "abc");" and it
worked. Why didn't it crash?

A: You got "lucky".

87: How much memory does a pointer variable allocate?

A: Only enough memory to hold the pointer itself, not any memory
for the pointer to point to.


88: Why am I getting "warning: assignment of pointer from integer
lacks a cast" for calls to malloc()?

A: Have you #included ?

89: Why does some code carefully cast the values returned by malloc
to the pointer type being allocated?

A: Before ANSI/ISO C, these casts were required to silence certain
warnings.

90: Why does so much code leave out the multiplication by
sizeof(char) when allocating strings?

A: Because sizeof(char) is, by definition, exactly 1.

91: I have a function that is supposed to return a string, but when
it returns to its caller, the returned string is garbage.

A: Make sure that the pointed-to memory is properly (i.e. not
locally) allocated.

92: So what's the right way to return a string?

A: Return a pointer to a statically-allocated buffer, a buffer
passed in by the caller, or memory obtained with malloc().

93: I've heard that some operating systems don't actually allocate
malloc'ed memory until the program tries to use it. Is this
legal?

A: It's hard to say.

94: Why doesn't the code "char *answer; gets(answer);" work?

A: The pointer variable answer has not been set to point to any
valid storage. The simplest way to correct this fragment is to
use a local array, instead of a pointer.

95: I can't get strcat() to work. I tried "char *s3 =
strcat(s1, s2);" but I got strange results.

A: Again, the main problem here is that space for the concatenated
result is not properly allocated.

96: I'm allocating a large array for some numeric work, but malloc()
is acting strangely.

A: Make sure the number you're trying to pass to malloc() isn't
bigger than a size_t can hold.

97: I've got 8 meg of memory in my PC. Why can I only seem to
malloc 640K or so?

A: Under the segmented architecture of PC compatibles, it can be
difficult to use more than 640K with any degree of transparency.

98: My program is crashing, apparently somewhere down inside malloc.

A: Make sure you aren't using more memory than you malloc'ed,
especially for strings (which need strlen(str) + 1 bytes).


99: Why isn't a pointer null after calling free()?

A: C's pass-by-value semantics mean that called functions can never
permanently change the values of their arguments.

100: When I call malloc() to allocate memory for a local pointer, do
I have to explicitly free() it?

A: Yes.

102: You can't use dynamically-allocated memory after you free it,
can you?

A: No. Some early documentation implied otherwise, but the claim
is no longer valid.

103: When I free a dynamically-allocated structure containing
pointers, do I also have to free each subsidiary pointer?

A: Yes.

104: Must I free allocated memory before the program exits?

A: You shouldn't have to.


105: How does free() know how many bytes to free?

A: The malloc/free implementation remembers the size of each block
as it is allocated.

106: So can I query the malloc package to find out how big an
allocated block is?

A: Not portably.

108: Is it legal to pass a null pointer as the first argument to
realloc()?

A: ANSI C sanctions this usage, although several earlier
implementations do not support it.

109: What is alloca() and why is its use discouraged?

A: alloca() allocates memory which is automatically freed when the
function which called alloca() returns. alloca() cannot be
written portably, is difficult to implement on machines without
a stack, and fails under certain conditions if implemented
simply.

110: What's the difference between calloc() and malloc()?

A: calloc() takes two arguments, and initializes the allocated
memory to all-bits-0.

111: Why doesn't my program's memory usage go down when I free
memory?

A: Most implementations of malloc/free do not return freed memory
to the operating system.

Section 9. Boolean Expressions and Variables

112: What is the right type to use for Boolean values in C?

A: There's no one right answer; see the full list for some
discussion.

113: What if a built-in logical or relational operator "returns"
something other than 1?

A: When a Boolean value is generated by a built-in operator, it is
guaranteed to be 1 or 0. (This is *not* true for some library
routines such as isalpha.)

114: Is if(p), where p is a pointer, valid?

A: Yes. See question 5.3.


Section 10. C Preprocessor

115: Where can I get a copy of a missing header file?

A: Contact your vendor, or see question 18.16 or the full list.

116: How can I construct preprocessor #if expressions which compare
strings?

A: You can't do it directly; try #defining several manifest
constants and implementing conditionals on those.

117: I've got some cute preprocessor macros that let me write C code
that looks more like Pascal. What do y'all think?

A: Bleah.

118: How can I write a generic macro to swap two values?

A: There is no good answer to this question. The best all-around
solution is probably to forget about using a macro.

119: What's the best way to write a multi-statement macro?

A: #define Func() do {stmt1; stmt2; ... } while(0) /* (no trailing ;) */

120: I'm getting strange syntax errors on the very first declaration
in a file, but it looks fine.

A: Perhaps there's a missing semicolon at the end of the last
declaration in the last header file you're #including.

121: What are .h files and what should I put in them?

A: Header files (also called ".h files") should generally contain
common declarations and macro, structure, and typedef
definitions, but not variable or function definitions.

122: Is it acceptable for one header file to #include another?

A: It's a question of style, and thus receives considerable debate.

123: What's the difference between #include <> and #include "" ?

A: Roughly speaking, the <> syntax is for Standard headers and ""
is for project headers.

124: What are the complete rules for header file searching?

A: The exact behavior is implementation-defined; see the full list
for some discussion.

125: How can I list all of the predefined identifiers?

A: If the compiler documentation is unhelpful, try extracting
printable strings from the compiler or preprocessor executable.

126: I have some old code that tries to construct identifiers with a
macro like "#define Paste(a, b) a/**/b", but it doesn't work any
more.

A: Try the ANSI token-pasting operator ##.


127: Does the sizeof operator work in preprocessor #if directives?

A: No.

128: Can I use an #ifdef in a #define line, to define something two
different ways?

A: No.

129: Is there anything like an #ifdef for typedefs?

A: Unfortunately, no.

130: How can I use a preprocessor #if expression to detect
endianness?

A: You probably can't.

131: How can I preprocess some code to remove selected conditional
compilations, without preprocessing everything?

A: Look for a program called unifdef, rmifdef, or scpp.


132: I've got this tricky preprocessing I want to do and I can't
figure out a way to do it.

A: Consider writing your own little special-purpose preprocessing
tool, instead.

133: How can I write a macro which takes a variable number of
arguments?

A: Here is one popular trick. Note that the parentheses around
printf's argument list are in the macro call, not the
definition.

#define DEBUG(args) (printf("DEBUG: "), printf args)

if(n != 0) DEBUG(("n is %d\n", n));

Section 8. Characters and Strings

134: Why doesn't "strcat(string, '!');" work?

A: strcat() concatenates *strings*, not characters.

135: Why won't the test if(string == "value") correctly compare
string against the value?

A: It's comparing pointers. To compare two strings, use strcmp().

136: Why can't I assign strings to character arrays?

A: Strings are arrays, and you can't assign arrays directly. Use
strcpy() instead.

137: How can I get the numeric (character set) value corresponding to
a character?

A: In C, if you have the character, you have its value.

138: Why is sizeof('a') not 1?

A: Character constants in C are of type int.


Section 11. ANSI/ISO Standard C

139: What is the "ANSI C Standard?"

A: In 1983, the American National Standards Institute (ANSI)
commissioned a committee to standardize the C language. Their
work was ratified as ANS X3.159-1989, and has since been adopted
as ISO/IEC 9899:1990, and later amended.

140: My ANSI compiler is complaining about prototype mismatches for
parameters declared float.

A: You have mixed the new-style prototype declaration
"extern int func(float);" with the old-style definition
"int func(x) float x;". "Narrow" types are treated differently
according to which syntax is used. This problem can be fixed by
avoiding narrow types, or by using either new-style (prototype)
or old-style syntax consistently.

141: Can you mix old-style and new-style function syntax?

A: Doing so is currently legal, for most argument types

142: Why does the declaration "extern int f(struct x *p);" give me a
warning message?

A: A structure declared (or even mentioned) for the first time
within a prototype cannot be compatible with other structures
declared in the same source file.

143: Why can't I use const values in initializers and array
dimensions?

A: The value of a const-qualified object is *not* a constant
expression in the full sense of the term.

144: How can I get a copy of the Standard?

A: Copies are available from ANSI in New York, or from Global
Engineering Documents in Englewood, CO, or from any national
standards body, or from ISO in Geneva, or republished within one
or more books. See the unabridged list for details.

145: Where can I get information about updates to the Standard?

A: See the full list for pointers.


146: What's the difference between "const char *p" and
"char * const p"?

A: The former declares a pointer to a constant character; the
latter declares a constant pointer to a character.

147: Why can't I pass a char ** to a function which expects a
const char **?

A: The rule which permits slight mismatches in qualified pointer
assignments is not applied recursively.

148: But what about main's third argument, envp?

A: It's a non-standard (though common) extension.

149: I believe that declaring void main() can't fail, since I'm
calling exit() instead of returning.

A: It doesn't matter whether main() returns or not, the problem is
that its caller may not even be able to *call* it correctly.

150: The book I've been using always uses void main().

A: It's wrong.

151: Is exit(status) truly equivalent to returning the same status
from main()?

A: Yes and no. (See the full list for details.)

152: How do I get the ANSI "stringizing" preprocessing operator `#'
to stringize the macro's value instead of its name?

A: You can use a two-step #definition to force a macro to be
expanded as well as stringized.


153: I'm getting strange syntax errors inside lines I've #ifdeffed
out.

A: Under ANSI C, #ifdeffed-out text must still consist of "valid
preprocessing tokens." This means that there must be no
newlines inside quotes, and no unterminated comments or quotes
(i.e. no single apostrophes).

154: What's the correct declaration of main()?

A: int main(int argc, char *argv[]) .

155: Can I declare main() as void, to shut off these annoying "main
returns no value" messages?

A: No.

156: I just tried some allegedly-undefined code on an ANSI-conforming
compiler, and got the results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior, including doing what you expect.

157: What are #pragmas ?

A: The #pragma directive provides a single, well-defined "escape
hatch" which can be used for extensions.

158: What does the message "warning: macro replacement within a
string literal" mean?

A: Some pre-ANSI compilers/preprocessors expanded macro parameters
even inside string literals and character constants.

159: What does "#pragma once" mean?

A: It is an extension implemented by some preprocessors to help
make header files idempotent.

160: Is char a[3] = "abc"; legal?

A: Yes, in ANSI C.

161: Why can't I perform arithmetic on a void * pointer?

A: The compiler doesn't know the size of the pointed-to objects.

162: Why does the ANSI Standard not guarantee more than six case-
insensitive characters of external identifier significance?

A: The problem is older linkers which cannot be forced (by mere
words in a Standard) to upgrade.

163: My compiler is rejecting the simplest possible test programs,
with all kinds of syntax errors.

A: Perhaps it is a pre-ANSI compiler.

164: Why are some ANSI/ISO Standard library functions showing up as
undefined, even though I've got an ANSI compiler?

A: Perhaps you don't have ANSI-compatible headers and libraries.

165: Does anyone have a tool for converting old-style C programs to
ANSI C, or for automatically generating prototypes?

A: See the full list for details.

166: What's the difference between memcpy() and memmove()?

A: memmove() offers guaranteed behavior if the source and
destination arguments overlap.

167: What should malloc(0) do?

A: The behavior is implementation-defined.


168: Why won't frobozz-cc, which claims to be ANSI compliant, accept
this code?

A: Are you sure that the code being rejected doesn't rely on some
non-Standard extension?

169: What's the difference between implementation-defined,
unspecified, and undefined behavior?

A: If you're writing portable code, ignore the distinctions.
Otherwise, see the full list.

170: I'm appalled that the ANSI Standard leaves so many issues
undefined.

A: In most of these cases, the Standard is simply codifying
existing practice.

Section 13. Library Functions

171: How can I convert numbers to strings?

A: Just use sprintf().

172: Why does strncpy() not always write a '\0'?

A: For mildly-interesting historical reasons.

173: Why do some versions of toupper() act strangely if given an
upper-case letter?

A: Older versions of toupper() and tolower() did not always work as
expected in this regard.

174: How can I split up a string into whitespace-separated fields?

A: Try strtok().

175: I need some code to do regular expression and wildcard matching.

A: regexp libraries abound; see the full list for details.

176: I'm trying to sort an array of strings with qsort(), using
strcmp() as the comparison function, but it's not working.

A: You'll have to write a "helper" comparison function which takes
two generic pointer arguments, converts them to char **, and
dereferences them, yielding char *'s which can be usefully
compared.

177: Now I'm trying to sort an array of structures, but the compiler
is complaining that the function is of the wrong type for
qsort().

A: The comparison function must be declared as accepting "generic
pointers" (const void *) which it then converts to structure
pointers.

178: How can I sort a linked list?

A: Algorithms like insertion sort and merge sort work well, or you
can keep the list in order as you build it.

179: How can I sort more data than will fit in memory?

A: You want an "external sort"; see the full list for details.

180: I need a random number generator.

A: The Standard C library has one: rand().

181: How can I get random integers in a certain range?

A: One method is something like

(int)((double)rand() / ((double)RAND_MAX + 1) * N)

182: Each time I run my program, I get the same sequence of numbers
back from rand().

A: You can call srand() to seed the pseudo-random number generator
with a truly random initial value.

183: What does it mean when the linker says that _end is undefined?

A: You generally get that message only when other symbols are
undefined, too.

184: I need a random true/false value, so I'm just taking rand() % 2,
but it's alternating 0, 1, 0, 1, 0...

A: Try using the higher-order bits: see question 13.16.

185: How can I get the time of day in a C program?

A: Just use the time(), ctime(), localtime() and/or strftime()
functions.

186: How can I convert a struct tm or a string into a time_t?

A: The ANSI mktime() function converts a struct tm to a time_t. No
standard routine exists to parse strings.

187: How can I perform calendar manipulations?

A: The ANSI/ISO Standard C mktime() and difftime() functions
provide some support for both problems.

188: Does C have any Year 2000 problems?

A: No, although poorly-written C programs do. Make sure you know
that tm_year holds the value of the year minus 1900.

189: How can I generate random numbers with a normal or Gaussian
distribution?

A: See the longer versions of this list for ideas.

190: I'm trying to port this old program. Why do I get "undefined
external" errors for some library functions?

A: Some semistandard functions have been renamed or replaced over
the years; see the full list for details.

191: I get errors due to library functions being undefined even
though I #include the right header files.

A: You may have to explicitly ask for the correct libraries to be
searched.

192: I'm still getting errors due to library functions being
undefined, even though I'm requesting the right libraries.

A: Library search order is significant; usually, you must search
the libraries last.

Section 14. Floating Point

193: When I set a float variable to 3.1, why is printf printing it as
3.0999999?

A: Most computers use base 2 for floating-point numbers, and many
fractions (including 0.1 decimal) are not exactly representable
in base 2.

194: My floating-point calculations are acting strangely and giving
me different answers on different machines.

A: First, see question 14.2 above. If the problem isn't that
simple, see the full list for a brief explanation, or any good
programming book for a better one.

195: What's a good way to check for "close enough" floating-point
equality?

A: The best way is to use an accuracy threshold which is relative
to the magnitude of the numbers being compared.

196: What's a good way to implement complex numbers in C?

A: It is straightforward to define a simple structure and some
arithmetic functions to manipulate them.

197: I'm looking for some mathematical library code.

A: See Ajay Shah's index of free numerical software at
ftp://ftp.math.psu.edu/pub/FAQ/numcomp-free-c .

198: I'm having trouble with a Turbo C program which crashes and says
something like "floating point formats not linked."

A: You may have to insert a dummy call to a floating-point library
function to force loading of floating-point support.

199: How do I round numbers?

A: For positive numbers, try (int)(x + 0.5) .

200: Where is C's exponentiation operator?

A: Try using the pow() function.

201: The predefined constant M_PI seems to be missing from .

A: That constant is not standard.

202: Why is sqrt(144.) giving me crazy numbers?

A: Make sure that you have #included , and correctly
declared other functions returning double.

203: I keep getting "undefined: sin" compilation errors.

A: Make sure you're actually linking with the math library.

204: How do I test for IEEE NaN and other special values?

A: There is not yet a portable way, but see the full list for
ideas.


Section 15. Variable-Length Argument Lists

205: I can't get va_arg() to pull in an argument of type pointer-to-
function.

A: Use a typedef.

206: How can I write a function which takes a variable number of
arguments and passes them to some other function ?

A: In general, you cannot.

207: How can I call a function with an argument list built up at run
time?

A: You can't.

208: Why don't function prototypes guard against mismatches in
printf's arguments?

A: Function prototypes do not provide any information about the
number and types of variable arguments.

209: How can I write a function that takes a variable number of
arguments?

A: Use the header.

210: How can I write a function that takes a format string and a
variable number of arguments, like printf(), and passes them to
printf() to do most of the work?

A: Use vprintf(), vfprintf(), or vsprintf().

211: How can I write a function analogous to scanf(), that calls
scanf() to do most of the work?

A: C9X will support vscanf().

212: I have a pre-ANSI compiler, without . What can I do?

A: There's an older header, , which offers about the
same functionality.

213: I heard that you have to #include before calling
printf(). Why?

A: So that a proper prototype for printf() will be in scope.

214: How can %f be used for both float and double arguments in
printf()?

A: In variable-length argument lists, types char and short int are
promoted to int, and float is promoted to double.

215: How can I discover how many arguments a function was actually
called with?

A: Any function which takes a variable number of arguments must be
able to determine *from the arguments' values* how many of them
there are.

216: My compiler isn't letting me declare a function that accepts
*only* variable arguments.

A: Standard C requires at least one fixed argument.

217: Why isn't "va_arg(argp, float)" working?

A: Because the "default argument promotions" apply in variable-
length argument lists, you should always use
va_arg(argp, double).

Section 12. Stdio

218: What's wrong with the code "char c; while((c = getchar()) !=
EOF) ..."?

A: The variable to hold getchar's return value must be an int.

219: Why won't the code "while(!feof(infp)) {
fgets(buf, MAXLINE, infp); fputs(buf, outfp); }" work?

A: EOF is only indicated *after* an input routine fails.

220: My program's prompts and intermediate output don't always show
up on the screen.

A: It's best to use an explicit fflush(stdout) whenever output
should definitely be visible.


221: How can I print a '%' character with printf?

A: "%%".

222: How can printf() use %f for type double, if scanf() requires
%lf?

A: C's "default argument promotions" mean that values of type float
are promoted to double.

223: What printf format should I use for a typedef when I don't know
the underlying type?

A: Use a cast to convert the value to a known type, then use the
printf format matching that type.

224: What's the difference between fgetpos/fsetpos and ftell/fseek?

A: fgetpos() and fsetpos() use a special typedef which may allow
them to work with larger files than ftell() and fseek().

225: Will fflush(stdin) flush unread characters from the standard
input stream?

A: No.

226: I'm trying to update a file in place, by using fopen mode "r+",
but it's not working.

A: Be sure to call fseek between reading and writing.


227: How can I implement a variable field width with printf?

A: Use printf("%*d", width, x).

228: How can I print numbers with commas separating the thousands?

A: There is no standard routine (but see ).

229: When I read numbers from the keyboard with scanf "%d\n", it
seems to hang until I type one extra line of input.

A: Try using "%d" instead of "%d\n".

230: I'm reading a number with scanf %d and then a string with
gets(), but the compiler seems to be skipping the call to
gets()!

A: scanf() and gets() do not work well together.

231: I'm re-prompting the user if scanf() fails, but sometimes it
seems to go into an infinite loop.

A: scanf() tends to "jam" on bad input since it does not discard
it.

232: Why does everyone say not to use scanf()? What should I use
instead?

A: scanf() has a number of problems. Usually, it's easier to read
entire lines and then interpret them.

233: Why doesn't the call scanf("%d", i) work?

A: The arguments you pass to scanf() must always be pointers.

234: Why doesn't the code "double d; scanf("%f", &d);" work?

A: Unlike printf(), scanf() uses %lf for double, and %f for float.

235: How can I specify a variable width in a scanf() format string?

A: You can't.


236: How can I tell how much destination buffer space I'll need for
an arbitrary sprintf call? How can I avoid overflowing the
destination buffer with sprintf()?

A: Use the new snprintf() function, if you can.

237: Why does everyone say not to use gets()?

A: It cannot be prevented from overflowing the input buffer.

238: Why does errno contain ENOTTY after a call to printf()?

A: Don't worry about it. It is only meaningful for a program to
inspect the contents of errno after an error has been reported.

239: How can I redirect stdin or stdout from within a program?

A: Use freopen().

240: Once I've used freopen(), how can I get the original stream
back?

A: There isn't a good way. Try avoiding freopen.

241: How can I arrange to have output go two places at once?

A: You could write your own printf variant which printed everything
twice.

242: How can I read a binary data file properly?

A: Be sure to specify "rb" mode when calling fopen().


Section 16. Strange Problems

243: I'm getting baffling syntax errors which make no sense at all,
and it seems like large chunks of my program aren't being
compiled.

A: Check for unclosed comments or mismatched preprocessing
directives.

244: Why isn't my procedure call working?

A: Function calls always require parenthesized argument lists.

245: This program crashes before it even runs!

A: Look for very large, local arrays.

246: I have a program that seems to run correctly, but then crashes
as it's exiting.

A: See the full list for ideas.

246: This program runs perfectly on one machine, but I get weird
results on another.

A: See the full list for a brief list of possibilities.

247: Why does the code "char *p = "hello, world!"; p[0] = 'H';"
crash?

A: String literals are not modifiable, except (in effect) when they
are used as array initializers.

248: What does "Segmentation violation" mean?

A: It generally means that your program tried to access memory it
shouldn't have, invariably as a result of stack corruption or
improper pointer use.


Section 17. Style

249: What's the best style for code layout in C?

A: There is no one "best style," but see the full list for a few
suggestions.

250: Is the code "if(!strcmp(s1, s2))" good style?

A: Not particularly.


251: Some people say that goto's are evil and that I should never use
them. Isn't that a bit extreme?

A: Yes. Absolute rules are an imperfect approach to good
programming style.

252: Why do some people write if(0 == x) instead of if(x == 0)?

A: It's a trick to guard against the common error of writing
if(x = 0) .

253: I came across some code that puts a (void) cast before each call
to printf(). Why?

A: To suppress warnings about otherwise discarded return values.

254: What is "Hungarian Notation"?

A: It's a naming convention which encodes information about a
variable's type in its name.

255: Where can I get the "Indian Hill Style Guide" and other coding
standards?

A: See the unabridged list.

Section 18. Tools and Resources

256: I'm looking for C development tools (cross-reference generators,
code beautifiers, etc.).

A: See the full list for a few names.

257: How can I track down these pesky malloc problems?

A: See the full list for a list of tools.

258: What's a free or cheap C compiler I can use?

A: See the full list for a brief catalog.

259: I just typed in this program, and it's acting strangely. Can
you see anything wrong with it?

A: See if you can run lint first.

260: How can I shut off the "warning: possible pointer alignment
problem" message which lint gives me for each call to malloc()?

A: It may be easier simply to ignore the message, perhaps in an
automated way with grep -v.

261: Where can I get an ANSI-compatible lint?

A: See the unabridged list for two commercial products.

262: Don't ANSI function prototypes render lint obsolete?

A: No. A good compiler may match most of lint's diagnostics; few
provide all.

263: Are there any C tutorials or other resources on the net?

A: There are several of them.

264: What's a good book for learning C?

A: There are far too many books on C to list here; the full list
contains a few pointers.

265: Where can I find the sources of the standard C libraries?

A: Several possibilites are listed in the full list.

266: Is there an on-line C reference manual?

A: Two possibilities are
http://www.cs.man.ac.uk/standard_c/_index.html and
http://www.dinkumware.com/htm_cl/index.html .


267: I need code to parse and evaluate expressions.

A: Several available packages are mentioned in the full list.

268: Where can I get a BNF or YACC grammar for C?

A: See the ANSI Standard, or the unabridged list.

269: Does anyone have a C compiler test suite I can use?

A: See the full list for several sources.

270: Where are some collections of useful code fragments and
examples?

A: See the full list for a few sources.

271: I need code for performing multiple precision arithmetic.

A: See the full list for a few ideas.

272: Where and how can I get copies of all these freely distributable
programs?

A: See the regular postings in the comp.sources.unix and
comp.sources.misc newsgroups, or the full version of this list,
for information.


Section 19. System Dependencies

273: How can I read a single character from the keyboard without
waiting for the RETURN key?

A: Alas, there is no standard or portable way to do this sort of
thing in C.

274: How can I find out how many characters are available for
reading, or do a non-blocking read?

A: These, too, are entirely operating-system-specific.

275: How can I display a percentage-done indication that updates
itself in place, or show one of those "twirling baton" progress
indicators?

A: The character '\r' is a carriage return, and '\b' is a
backspace.

276: How can I clear the screen, or print text in color, or move the
cursor?

A: The only halfway-portable solution is the curses library.

277: How do I read the arrow keys? What about function keys?

A: Such things depend on the keyboard, operating system, and
library you're using.

278: How do I read the mouse?

A: What system are you using?

279: How can I do serial ("comm") port I/O?

A: It's system-dependent.

280: How can I direct output to the printer?

A: See the full list for ideas.

281: How do I send escape sequences to control a terminal or other
device?

A: By sending them. ESC is '\033' in ASCII.

282: How can I do graphics?

A: There is no portable way.

283: How can I check whether a file exists?

A: You can try the access() or stat() functions. Otherwise, the
only guaranteed and portable way is to try opening the file.

284: How can I find out the size of a file, prior to reading it in?

A: You might be able to get an estimate using stat() or fseek/ftell
(but see the full list for caveats).

285: How can I find the modification date of a file?

A: Try stat().

286: How can a file be shortened in-place without completely clearing
or rewriting it?

A: There are various ways to do this, but there is no portable
solution.

287: How can I insert or delete a line in the middle of a file?

A: Short of rewriting the file, you probably can't.

288: How can I recover the file name given an open file descriptor?

A: This problem is, in general, insoluble. It is best to remember
the names of files yourself as you open them

289: How can I delete a file?

A: The Standard C Library function is remove().

290: How do I copy files?

A: Open the source and destination files and copy a character or
block at a time, or see question 19.27.

291: What's wrong with the call fopen("c:\newdir\file.dat", "r")?

A: You probably need to double those backslashes.

292: How can I increase the allowable number of simultaneously open
files?

A: Check your system documentation.

291: How can I read a directory in a C program?

A: See if you can use the opendir() and readdir() functions.

292: How can I find out how much memory is available?

A: Your operating system may provide a routine which returns this
information.

293: How can I allocate arrays or structures bigger than 64K?

A: Some operating systems won't let you.

294: What does the error message "DGROUP exceeds 64K" mean?

A: It means that you have too much static data.

295: How can I access memory located at a certain address?

A: Set a pointer to the absolute address.

296: How can I invoke another program from within a C program?

A: Use system().

297: How can I invoke another program and trap its output?

A: Unix and some other systems provide a popen() function.

298: How can my program discover the complete pathname to the
executable from which it was invoked?

A: argv[0] may contain all or part of the pathname. You may be
able to duplicate the command language interpreter's search path
logic to locate the executable.

299: How can I automatically locate a program's configuration files
in the same directory as the executable?

A: It's hard; see also question 19.31 above.

300: How can a process change an environment variable in its caller?

A: If it's possible to do so at all, it's system dependent.

301: How can I read in an object file and jump to locations in it?

A: You want a dynamic linker or loader.

302: How can I implement a delay, or time a user's response, with sub-
second resolution?

A: Unfortunately, there is no portable way.

303: How can I trap or ignore keyboard interrupts like control-C?

A: Use signal().

304: How can I handle floating-point exceptions gracefully?

A: Take a look at matherr() and signal(SIGFPE).

305: How do I... Use sockets? Do networking? Write client/server
applications?

A: These questions have more to do with the networking facilities
you have available than they do with C.

306: How do I... Use BIOS calls? Write ISR's? Create TSR's?

A: These are very particular to a particular system.

307: I'm trying to compile a program in which "union REGS" and
int86() are undefined.

A: Those have to do with MS-DOS interrupt programming.

308: But I can't use all these nonstandard, system-dependent
functions, because my program has to be ANSI compatible!

A: That's an impossible requirement. Any real program requires at
least a few services which ANSI doesn't define.


Section 20. Miscellaneous

309: How can I return multiple values from a function?

A: Either pass pointers to several locations which the function can
fill in, or have the function return a structure containing the
desired values.

310: How do I access command-line arguments?

A: Via main()'s argv parameter.

311: How can I write data files which can be read on other machines
with different data formats?

A: The most portable solution is to use text files.

312: How can I call a function, given its name as a string?

A: The most straightforward thing to do is to maintain a
correspondence table of names and function pointers.

313: How can I implement sets or arrays of bits?

A: Use arrays of char or int, with a few macros to access the
desired bit at the proper index.

314: How can I determine whether a machine's byte order is big-endian
or little-endian?

A: The usual tricks involve pointers or unions.

315: How can I convert integers to binary or hexadecimal?

A: Internally, integers are already in binary. During I/O, you may
be able to select a base.

316: Can I use base-2 constants (something like 0b101010)?
Is there a printf() format for binary?

A: No, on both counts.

317: What is the most efficient way to count the number of bits which
are set in an integer?

A: Many "bit-fiddling" problems like this one can be sped up and
streamlined using lookup tables.

318: What's the best way of making my program efficient?

A: By picking good algorithms and implementing them carefully.

319: Are pointers really faster than arrays? How much do function
calls slow things down?

A: Precise answers to these and many similar questions depend on
the processor and compiler in use.

320: People claim that optimizing compilers are good, but mine can't
even replace i/=2 with a shift.

A: Was i signed or unsigned?

321: How can I swap two values without using a temporary?

A: The "clever" trick is a ^= b; b ^= a; a ^= b; .

322: Is there a way to switch on strings?

A: Not directly.

323: Is there a way to have non-constant case labels (i.e. ranges or
arbitrary expressions)?

A: No.

324: Are the outer parentheses in return statements really optional?

A: Yes.

325: Why don't C comments nest? Are they legal inside quoted
strings?

A: C comments don't nest because PL/I's comments don't either. The
character sequences /* and */ are not special within double-
quoted strings.

326: What does a+++++b mean ?

A: Nothing. It's interpreted as "a ++ ++ + b", and cannot be
parsed.

327: Why doesn't C have nested functions?

A: They were deliberately left out of C as a simplification.

328: What is assert()?

A: It is a macro which documents an assumption being made by the
programmer; it terminates the program if the assumption is
violated.

329: How can I call FORTRAN (C++, BASIC, Pascal, Ada, LISP) functions
from C?

A: The answer is entirely dependent on the machine and the specific
calling sequences of the various compilers in use.

330: Does anyone know of a program for converting Pascal or FORTRAN
to C?

A: Several freely distributable programs are available, namely
ptoc, p2c, and f2c. See the full list for details.

331: Can I use a C++ compiler to compile C code?

A: Not necessarily; C++ is not a strict superset of C.

332: I need to compare two strings for close, but not necessarily
exact, equality.

A: See the full list for ideas.

333: What is hashing?

A: A mapping of strings (or other data structures) to integers, for
easier searching.

334: How can I find the day of the week given the date?

A: Use mktime(), Zeller's congruence, or some code in the full
list.

335: Will 2000 be a leap year?

A: Yes.

336: How do you write a program which produces its own source code as
output?

A: Here's one:

char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";
main(){printf(s,34,s,34);}

337: What is "Duff's Device"?

A: It's a devastatingly deviously unrolled byte-copying loop. See
the full list for details.

338: What was the entry keyword mentioned in K&R1?

A: It was reserved to allow functions with multiple, differently-
named entry points, but it has been withdrawn.

339: Where does the name "C" come from, anyway?

A: C was derived from B, which was inspired by BCPL, which was a
simplification of CPL.

340: How do you pronounce "char"?

A: Like the English words "char," "care," or "car" (your choice).

341: What do "lvalue" and "rvalue" mean?

A: An "lvalue" denotes an object that has a location; an "rvalue"
is any expression that has a value.