C Program: how can result of 1st few lines of code change based on what happens much later in program?

StackOverflow https://stackoverflow.com/questions/10038355

  •  29-05-2021
  •  | 
  •  

Pergunta

I'm programming some C code using gcc -std=C89 switch on a Linux box. This C code communicates with an Oracle database using OCI drivers called by OCILIB libraries. After downloading the necessary data from the database, the C program calls a C function (my_function) that performs a lot of complex math. The program flow looks like:

int main (void) {
    OCI_Connection *cn; 
    OCI_Statement  *st;
    OCI_Resultset  *rs; 
    ...
    /* FIRST CALL TO DB */
    OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT);
    cn = OCI_ConnectionCreate(...);
    st = OCI_StatementCreate(cn);
    OCI_Prepare(st, ...);
    OCI_Bindxxx(st, ...);
    OCI_Execute(st);

    printf(...); /* verify data retrieved from database is correct */

    /* SECOND CALL TO DB */
    OCI_Prepare(st, ...); /* different prepare stmt than above */
    OCI_Bindxxx(st, ...);
    OCI_Execute(st, ...);

    printf(...); /* verify data retrieved from database is correct */

    /* THIRD CALL TO DB */
    OCI_SetFetchSize(st, 200);
    OCI_Prepare(st, ...);
    OCI_Bindxxx(st, ...);
    OCI_Execute(st);
    rs = OCI_GetResultset(st);
    ...
    printf(...); /* verify data retrieved from database is correct */

    OCI_Cleanup();
    return EXIT_SUCCESS;

    my_function(...);
}

If I run the program as shown, the printf statements all display the correct data has been downloaded from the database into the C program. However, my_function has not executed.

If I then move the return EXIT_SUCCESS line of code from before my_function() to AFTER my_function(), re-compile the code and run it, the printf statements show that the data from the 1st call to the database is saved correctly in the C program, but the 2nd call's data is incorrect, and the printf statement from the 3rd call appears not to have done anything.

There are no errors or warnings reported at compile and run time.

I'm not that experienced in C (or OCILIB), but for those who are, is there a logical explanation how the placement of return EXIT_SUCCESS in the code can interact with code located much before it, to cause this?

In my simple mind, I think of the code as executing one line at a time, so if the code works to line 123 (for example), a change to the code at line 456 shouldn't effect the results up to line 123 (e.g. when comparing before-versus-after the change to line 456). Perhaps Am I missing something?

Foi útil?

Solução

Another possibility is that your code is relying on the value of uninitialized variables, and that by adding the return before calling myfunction() you are changing the way the compiler lays out variables in memory.

For example, an optimizing compiler might notice that the call to myfunction() is unreachable because of the return, thus it might be able to avoid setting aside space for a temporary variable it might otherwise need for the myfunction() call.

Make sure your compiler is set to warn about use of uninitialized variables.

Outras dicas

I'm guessing that your printf statements don't end in newlines; in this case, the output isn't flushed until the main ends. This allows for my_function to corrupt stdout in the meantime. Use newlines or fflush and I'll bet this apparently anomalous behavior will cease.

Rewritten answer:

If your code is behaving as differently as you describe, it suggests that the version with the return before your call doesn't include your function in its executable image (the unused code is optimized out), which changes the memory layout. This then might be affecting your code if you have serious memory management issues.

Did you try reprinting the first data after the second lot of database activity, to ensure that you still had the information you thought you had read successfully? Was your printing of the information retrieved thorough and complete?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top