Using a nonexistent header file should lead to an error message

Issue #229 wontfix
Ian Hinder created an issue

If I have the following in my interface.ccl,

USES INCLUDE: vectors.h

but no thorn in my thornlist provides this header file, there is no error at compile time. Further, if I #include this file in my source file, an empty file is included, which means that again I don't get an error. The first indication that something is wrong is that the contents of the header file are not available, which makes debugging the problem with the thornlist very confusing.

I propose that the CST should emit a fatal error if one of the thorns tries to use a header file which does not exist.

Keyword:

Comments (15)

  1. Erik Schnetter
    • removed comment

    This is actually a feature of the Cactus include file mechanism: Several thorns can contribute towards an include file, and it is not an error if no thorn provides anything. This allows thorns to provide optional capabilities.

    One example is LoopControl, which provides a header file loopcontrol.h. This header file overwrites (improves upon) the looping constructs provided by the flesh (in cctk_Loop.h). Other thorns can include this file, independent of whether LoopControl is in the thorn list or not. This makes it possible to write thorns that use LoopControl, and which still work if LoopControl is not present.

    The original motivation for this include mechanism was matter thorns, i.e. thorns contributing to Tmunu. A spacetime thorn could thus include matter terms via a header file, and would thus work independent of whether any matter thorns are present or not.

  2. Ian Hinder reporter
    • removed comment

    As in Ticket #217, it would be nice if the default behaviour was more intuitive, and the functionality for allowing the file to be included even if it doesn't exist could be enabled by an additional keyword.

    In any case, the behaviour should be documented in the user guide. I can add that documentation if we decide that we don't want to change things.

  3. Frank Löffler
    • removed comment

    It sounds like the thorn providing this header file should provide a Cactus capability which the other thorn which depends on that very header file then would require.

  4. Erik Schnetter
    • removed comment

    The thorn providing this header file does provide this capability. The thorn using this header file did not require this capability, and thus the error checking did not work out as expected.

  5. Ian Hinder reporter
    • removed comment

    Is it necessary to require a particular capability in order to include a header file?

    I thought that the two things were orthogonal. In fact, if it is possible for more than one active thorn to provide a header file, and only one thorn providing a given capability can be active at one time, it would not be possible to make the provision of a header file entail requirement of an associated capability. So the two concepts are distinct.

  6. Frank Löffler
    • removed comment

    It is not necessary to require a particular capability in order to include _some_ header file.

    The Cactus-mechanism for header-files is more like 'I would like to include whatever other thorns provide under that header-name, if any.' This does not introduce a dependency of thorns.

    This is not what you want in your case. In your case you want one particular header file: that of thorn LoopControl. There should not be another thorn providing this file, and for sure not multiple. You have to have LoopControl to have that file, thus the required dependency.

  7. Erik Schnetter
    • removed comment

    Thorn LoopControl is optional. It provides a header file loopcontrol.h that overrides some flesh macros with different, potentially more efficient ones. When writing a thorn, one does not want to decide whether LoopControl is present or not.

    Thus LoopControl adds to the loopcontrol.h include file if present, and if not present, this include file is empty. Thorns can unconditionally include loopcontrol.h, as long as they declare "USES INCLUDE loopcontrol.h" in their interface.ccl

    This is independent of capabilities. The optional capability is there to create the correct link order (and, in general, to tell Cactus about this direct dependency between the thorns), because the macros in LoopControl.h's loopcontrol.h call some functions defined in LoopControl.h.

  8. Ian Hinder reporter

    Let's ignore LoopControl now, as that was not the thorn that I had the problem with. I was using the Vectors thorn, and in my thorn I asked for the vectors.h header file. The thorn Vectors was not in my thorn list.

    The correct thing to do if you want to use Vectors is to "require" the Vectors capability. If I had done that, I would have gotten a fatal error that there was no thorn providing that capability, which would have directed me to the solution of the problem (to include Vectors in my thornlist).

    Instead, I simply asked for the header file, and the Cactus header file mechanism gives you an empty header file if no thorn provides one. My point is that this is counterintuitive. I would like for Cactus to give an error if you ask for a header file which does not exist. In order to support the case that this might be a valid situation, thorns could specify

    OPTIONALLY USES INCLUDE: vectors.h

    if it can deal with the header file being empty.

  9. Erik Schnetter
    • removed comment

    The "uses include" and "uses include header" mechanism was designed to combine multiple files into one. For example, Cactus makes copies of these files, and there is no error when two thorns provide the same header file -- they are concatenated. This is also probably something that few people expect.

    I want to argue that this mechanism is not what we want to use here at all. Instead, thorn Vectors should set up the include path so that the header files it provides are found by other thorns. Other thorns then say "#include <...>", and if the include file is not found, it is clear what is going wrong -- the include path is not set correctly, which is something every C programmer is familiar with.

  10. Ian Hinder reporter
    • removed comment

    Perhaps, but if you agree that the behaviour of the Cactus include mechanism is confusing, do you agree that it could be modified to make it less so in the way I suggested?

  11. Erik Schnetter
    • removed comment

    The Cactus include mechanism was designed to allow inlining across multiple thorns, in particular to allow inlining the calculation of Tmunu. Given that running without hydro is not an uncommon case, what you propose isn't just a small change, it requires rethinking the whole concept.

    For example, multiple thorns can contribute code towards an include file. What do you suggest should happen in this case? Would you find it surprising if two thorns provided different code for the same include file?

  12. Frank Löffler
    • removed comment

    I agree with Erik, that we don't really need a new mechanism. We already have two, and the only important part is to 'teach' users to use the one they need, because otherwise unsurprisingly they don't get what they think they do.

    Concerning this ticket: should we keep it open? Should we instead discuss this on the mailing list?

  13. Roland Haas
    • edited description
    • changed status to wontfix

    As discussed in the ticket, the functionality of USE INCLUDE and USE INCLUDE HEADER functions as documented and relies on not producing errors if no thorn provides the header files. If the content of the file is relied on then the correct way is to REQUIRE a capability of a thorn that promises to provide the header file. This is the same as REQUIREing the MPI capability to gain access to mpi.h.

    If indeed a separate mechanism mirroring this for include files is desired it should, following the example set by USES FUNCTION and REQUIRES FUNCTION, be called REQUIRES INCLUDE and REQUIRES INCLUDE HEADER.

  14. Log in to comment