mouse07410 / asn1c

The ASN.1 Compiler
http://lionet.info/asn1c/
BSD 2-Clause "Simplified" License
93 stars 70 forks source link

Circular Reference in Generated C Code for NodeOffsetPointXY structure #189

Closed dmccoystephenson closed 2 months ago

dmccoystephenson commented 4 months ago

Problem

A circular reference of header imports is present in the C code generated from the ASN.1 Compiler. The generated file (Header A) depends on a structure defined in another header file (Header B), which indirectly depends on Header A.

Current Workaround

This can be worked around by inserting a declaration of the structure defined in Header B before it is used, and moving the include statement for Header B such that it is after the usage of the structure.

Context

The NodeOffsetPointXY structure is part of the J2735 2020 specification. The ASN files can be downloaded from the SaE website.

Potential Solutions

Some potential solutions that do not require the developer/user to modify the generated header directly include the following:

  1. Identify root cause of circular dependency generation and fix the problem.
  2. Modify the compiler to identify circular dependencies and attempt to make modifications to make generated files usable despite them.

Relevant Error Message

Attempting to build the converter-example program resulted in an error with the NodeOffsetPointXY header class:

In file included from /output/2020/SignalHeadLocationList.h:44:0, from /output/2020/MapData-addGrpC.h:46, from /output/2020/RegionalExtension.h:25, from /output/2020/NodeOffsetPointXY.h:22, from /output/2020/ConnectionManeuverAssist-addGrpC.h:44, from /output/2020/ConnectionManeuverAssist-addGrpC.c:8: /output/2020/SignalHeadLocation.h:25:2: error: unknown type name 'NodeOffsetPointXY_t' NodeOffsetPointXY_t node; ^~~~~~~ converter-example.mk:19: recipe for target '/output/2020/ConnectionManeuverAssist-addGrpC.o' failed make: *** [/output/2020/ConnectionManeuverAssist-addGrpC.o] Error 1

This is due to attempting to use a structure prior to its declaration. After overriding the header file with a modified version, the converter-example program was compiled with no issues.

Summary

To summarize, NodeOffsetPointXY.h includes RegionalExtension.h, which imports MapData-addGrpC.h, which imports SignalHeadLocationList.h, which attempts to reference NodeOffsetPointXY_t (defined in NodeOffsetPointXY.h). The ‘NodeOffsetPointXY.h’ header file indirectly attempts to include itself.

Diagram

The following diagram depicts the circular reference:

image

mouse07410 commented 2 months ago

Thank you for reporting this, and providing a workaround.

Regarding potential solutions - unless you're willing to implement it and submit a PR, I have neither time nor sufficient competence to muck with the ASN.1 compiler to the degree necessary.

So, closing this issue as unlikely to be fixed by me. If/when you implement one of your potential solutions - your PR would be welcome here.

dmccoystephenson commented 2 months ago

Thanks for the reply! I have opened this issue on a separate fork.

mouse07410 commented 2 months ago

Would you mind posting here the link to the issue you opened?

dmccoystephenson commented 2 months ago

Would you mind posting here the link to the issue you opened?

Here you go! https://github.com/usdot-fhwa-stol/usdot-asn1c/issues/1

v0-e commented 1 month ago

Hey @dmccoystephenson, you can try compiling with the -fno-include-deps flag. While it isn't the optimal solution, it may solve your issue.

dmccoystephenson commented 1 month ago

Hey @dmccoystephenson, you can try compiling with the -fno-include-deps flag. While it isn't the optimal solution, it may solve your issue.

Hey @v0-e, I appreciate the response! I did some preliminary testing using the -fno-include-deps flag and this does appear to solve the compilation issue that occurs when compiling the converter-example program.

Further testing will be necessary to ensure the asn1_codec project still functions as expected when utilizing this argument, but this is very promising!